bake: deduplicate context transfer use case

Co-authored-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax 2024-06-24 11:46:40 +02:00
parent 2b2eb44c4b
commit 439e0b7cd2
No known key found for this signature in database
GPG Key ID: ADE44D8C9D44FBE4
1 changed files with 82 additions and 0 deletions

View File

@ -88,3 +88,85 @@ target "app" {
In most cases you should just use a single multi-stage Dockerfile with multiple
targets for similar behavior. This case is only recommended when you have
multiple Dockerfiles that can't be easily merged into one.
## Deduplicate context transfer
When you build targets concurrently, using groups, build contexts are loaded
independently for each target. If the same context is used by multiple targets
in a group, that context is transferred once for each time it's used. This can
result in significant impact on build time, depending on your build
configuration. For example, say you have a Bake file that defines the following
group of targets:
```hcl
group "default" {
targets = ["target1", "target2"]
}
target "target1" {
target = "target1"
context = "."
}
target "target2" {
target = "target2"
context = "."
}
```
In this case, the context `.` is transferred twice when you build the default
group: once for `target1` and once for `target2`.
If your context is small, and if you are using a local builder, duplicate
context transfers may not be a big deal. But if your build context is big, or
you have a large number of targets, or you're transferring the context over a
network to a remote builder, context transfer becomes a performance bottleneck.
To avoid transferring the same context multiple times, you can define a named
context that only loads the context files, and have each target that needs
those files reference that named context. For example, the following Bake file
defines a named target `ctx`, which is used by both `target1` and `target2`:
```hcl
group "default" {
targets = ["target1", "target2"]
}
target "ctx" {
context = "."
target = "ctx"
}
target "target1" {
target = "target1"
contexts = {
ctx = "target:ctx"
}
}
target "target2" {
target = "target2"
contexts = {
ctx = "target:ctx"
}
}
```
The named context `ctx` represents a Dockerfile stage, which copies the files
from its context (`.`). Other stages in the Dockerfile can now reference the
`ctx` named context and, for example, mount its files with `--mount=from=ctx`.
```dockerfile
FROM scratch AS ctx
COPY --link . .
FROM golang:alpine AS target1
WORKDIR /work
RUN --mount=from=ctx \
go build -o /out/client ./cmd/client \
FROM golang:alpine AS target2
WORKDIR /work
RUN --mount=from=ctx \
go build -o /out/server ./cmd/server
```