---
title: Mastering multi-platform builds, testing, and more with Docker Buildx Bake
linkTitle: Mastering Docker Buildx Bake
description: >
Learn how to manage simple and complex build configurations with Buildx Bake.
summary: >
Learn to automate Docker builds and testing with declarative configurations using Buildx Bake.
tags: [devops]
languages: [go]
params:
time: 30 minutes
featured: true
image: /images/guides/bake.webp
---
This guide demonstrates how to simplify and automate the process of building
images, testing, and generating build artifacts using Docker Buildx Bake. By
defining build configurations in a declarative `docker-bake.hcl` file, you can
eliminate manual scripts and enable efficient workflows for complex builds,
testing, and artifact generation.
## Assumptions
This guide assumes that you're familiar with:
- Docker
- [Buildx](/manuals/build/concepts/overview.md#buildx)
- [BuildKit](/manuals/build/concepts/overview.md#buildkit)
- [Multi-stage builds](/manuals/build/building/multi-stage.md)
- [Multi-platform builds](/manuals/build/building/multi-platform.md)
## Prerequisites
- You have a recent version of Docker installed on your machine.
- You have Git installed for cloning repositories.
- You're using the [containerd](/manuals/desktop/features/containerd.md) image store.
## Introduction
This guide uses an example project to demonstrate how Docker Buildx Bake can
streamline your build and test workflows. The repository includes both a
Dockerfile and a `docker-bake.hcl` file, giving you a ready-to-use setup to try
out Bake commands.
Start by cloning the example repository:
```bash
git clone https://github.com/dvdksn/bakeme.git
cd bakeme
```
The Bake file, `docker-bake.hcl`, defines the build targets in a declarative
syntax, using targets and groups, allowing you to manage complex builds
efficiently.
Here's what the Bake file looks like out-of-the-box:
```hcl
target "default" {
target = "image"
tags = [
"bakeme:latest",
]
attest = [
"type=provenance,mode=max",
"type=sbom",
]
platforms = [
"linux/amd64",
"linux/arm64",
"linux/riscv64",
]
}
```
The `target` keyword defines a build target for Bake. The `default` target
defines the target to build when no specific target is specified on the command
line. Here's a quick summary of the options for the `default` target:
- `target`: The target build stage in the Dockerfile.
- `tags`: Tags to assign to the image.
- `attest`: [Attestations](/manuals/build/metadata/attestations/_index.md) to attach to the image.
> [!TIP]
> The attestations provide metadata such as build provenance, which tracks
> the source of the image's build, and an SBOM (Software Bill of Materials),
> useful for security audits and compliance.
- `platforms`: Platform variants to build.
To execute this build, simply run the following command in the root of the
repository:
```console
$ docker buildx bake
```
With Bake, you avoid long, hard-to-remember command-line incantations,
simplifying build configuration management by replacing manual, error-prone
scripts with a structured configuration file.
For contrast, here's what this build command would look like without Bake:
```console
$ docker buildx build \
--target=image \
--tag=bakeme:latest \
--provenance=true \
--sbom=true \
--platform=linux/amd64,linux/arm64,linux/riscv64 \
.
```
## Testing and linting
Bake isn't just for defining build configurations and running builds. You can
also use Bake to run your tests, effectively using BuildKit as a task runner.
Running your tests in containers is great for ensuring reproducible results.
This section shows how to add two types of tests:
- Unit testing with `go test`.
- Linting for style violations with `golangci-lint`.
In Test-Driven Development (TDD) fashion, start by adding a new `test` target
to the Bake file:
```hcl
target "test" {
target = "test"
output = ["type=cacheonly"]
}
```
> [!TIP]
> Using `type=cacheonly` ensures that the build output is effectively