Long docker build command lines belong in a file. docker buildx bake reads build definitions from docker-bake.hcl (HCL, JSON or a Compose 514 file also work) and builds several targets in one parallel run. BookNest's file defines the runtime image, the test image and a multi-platform variant, with names that a CI job overrides through environment variables:
# BookNest's build targets. Override IMAGE and TAG from the environment.
variable "IMAGE" { default = "booknest-api" }
variable "TAG" { default = "dev" }
group "default" {
targets = ["api", "test"]
}
target "api" {
target = "runtime"
tags = ["${IMAGE}:${TAG}"]
}
target "test" {
target = "test"
tags = ["${IMAGE}:${TAG}-test"]
}
target "api-multi" {
inherits = ["api"]
platforms = ["linux/amd64", "linux/arm64"]
}docker buildx bake --list targets
IMAGE=l3-booknest-api TAG=1.2 docker buildx bake --progress=plain 2>&1 |
grep -E 'reading|naming'
git add Dockerfile docker-bake.hcl
git commit -q -m "Build the dependency stages natively; add docker-bake.hcl"
git log --oneline -1... TARGET DESCRIPTION api api-multi default api, test test #1 reading docker-compose.yml 1.19kB / 1.19kB done #1 reading docker-bake.hcl 437B / 437B done ... #14 naming to docker.io/library/l3-booknest-api:1.2-test done #21 naming to docker.io/library/l3-booknest-api:1.2 done 82fbb6f Build the dependency stages natively; add docker-bake.hcl
One command built both images, sharing the base stage. Note that bake also read docker-compose.yml: it merges Compose services that have a build section into its targets. --print api shows a target's resolved definition as JSON without building, --set api.platform=linux/arm64 overrides a value for one run, and docker buildx bake api-multi builds both platforms.