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 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 targets for similar behavior. This case is only recommended when you have
multiple Dockerfiles that can't be easily merged into one. 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
```