Skip to content

Build1 publisher3 min readPublished

Docker Bake prints the resolved build configuration before it builds anything

A two-part dev.to series walks through the Buildx subcommand that collapses multi-target image builds into HCL files, where the variables live in a separate file and a print flag shows the fully interpolated configuration before anything is pushed.

The Engineer · Build desk

Illustration accompanying Docker Bake prints the resolved build configuration before it builds anything

What happened

  • The first part of a two-part dev.to series covers what Docker Bake is and why it exists, and the second part will cover Cloud Build, GitHub Actions, GitLab CI and Dagger.
  • Bake is a Buildx subcommand that reads HCL, JSON or Compose files and orchestrates many image builds at once, with shared variables, inheritance, matrices and groups.
  • BuildKit is the engine underneath, the default in Docker Engine 23 and later, already building Dockerfile stages in parallel and handling cache mounts, secrets and SSH forwarding.
  • The base invocation is `docker buildx bake -f vars.hcl -f docker-bake-app-and-infra.hcl`, and adding `--push` builds and publishes the same targets.
  • The author says he has given this talk for two years at DevLille, DevFest Toulouse, DevFest Lyon, Devoxx Morocco and Cloud Native Days France.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • cost For anyone on a recent Docker Desktop there is nothing new to install, so the cost is a day of HCL plus splitting variables into their own file, and it falls to whoever currently owns the wrapper script.
  • constraint Bake stops at producing images, so a team whose script also starts test containers keeps a run step in some other tool; the series itself hands that step to Compose.
  • decision With no build-time figures published in Part 1, a team adopting Bake is deciding on maintainability alone and would have to time its own target set before claiming a speed win.

Run the print flag before anything else. `docker buildx bake -f vars.hcl -f docker-bake-app-and-infra.hcl --print` emits the resolved build configuration with the variables already interpolated [7]. A shell wrapper gives you the same information by running, or through an echo somebody remembered to add. The printed configuration is text a reviewer can read, and it comes from the same file set that will do the build.

Variables live in a file of their own, and six of the eight bake invocations in the playground repository start with `-f vars.hcl` [17]. That file is passed on the command line instead of being imported from inside the HCL, so every invocation that needs the variables has to list it [6][8][10].

Targets are named at the call site: the combined run is `docker buildx bake -f vars.hcl -f docker-bake-app-and-infra.hcl -f docker-bake-lint-and-test.hcl default validate`, which names `default` and `validate` explicitly [10]. The lint file on its own is invoked as `validate` [8]. The inheritance example gets its own file, and the matrix example runs as a bare `docker buildx bake` with no `-f` at all [11].

Bake orchestrates builds, and the series' own lint and test flow still hands the run step to Compose: it builds the images with the `validate` target, then starts them with `docker compose -f compose_lint_and_test.yaml up` [8][9]. A wrapper that builds and then runs its test containers gets shorter under Bake, and the run step stays.

Parallelism shows up at two levels of the stack: BuildKit builds Dockerfile stages in parallel where it can, manages the cache and handles multi-platform output, and it has been the default engine since Docker Engine 23 [13]. Bake adds concurrency across targets, plus shared variables, inheritance, matrices and groups [15]. That concurrency turns into wall-clock savings only when the targets are independent of each other and the builder has capacity to run more than one at a time.

The case the article makes is a maintenance case, and the author offers the audience reaction as evidence. After every talk, he writes, people say "I had no idea Bake could do that" or "I've been writing 200-line bash scripts to do exactly this" [3][4].

Buildx ships with Docker Desktop and bundles BuildKit [16], and bake is a Buildx subcommand [15], so there is nothing to install. Bake also accepts a Compose file as input [15], so a team can start from what it already has and move to HCL when it needs a matrix. I would reach for the file at three or more images in a repo; with two, the wrapper is fine. The examples push to Google Cloud Artifact Registry, and the article says changing the target tag is all that Docker Hub, ECR, ACR or GHCR require [12].

What to watch

  • Whether Part 2's Cloud Build, GitHub Actions, GitLab CI and Dagger examples reuse the same vars.hcl or redefine variables per platform.
  • The promised English walkthrough video on the author's YouTube channel, alongside the existing French Cloud Native Days France recording.
  • Whether the Compose-file input path to Bake gets the same matrix and inheritance examples as the HCL files do.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories