Three docker build invocations in a shell script share nothing and cannot run in parallel; a bake file describes them as a graph.
group "default" {
targets = ["php", "nginx", "worker"]
}
target "base" {
dockerfile = "docker/php/Dockerfile"
target = "base"
}
target "php" {
inherits = ["base"]
tags = ["registry/app-php:${TAG}"]
cache-from = ["type=gha"]
cache-to = ["type=gha,mode=max"]
}
# docker buildx bake --push
The inheritance is what makes it worth the file: the cache configuration, the build arguments and the platform list are declared once rather than repeated in three shell lines that will eventually disagree. It also reads a Compose file directly, so a project already describing its images there can bake without a second description. Variable interpolation from the environment covers the tag, which is the one thing that genuinely varies per build.