13 KiB
Bake file definition
buildx bake
supports HCL, JSON and Compose file format for defining build
groups, targets as well as variables and
functions. It looks for build definition files in the current
directory in the following order:
docker-compose.yml
docker-compose.yaml
docker-bake.json
docker-bake.override.json
docker-bake.hcl
docker-bake.override.hcl
Specification
Inside a bake file you can declare group, target and variable blocks to define project specific reusable build flows.
Target
A target reflects a single docker build invocation with the same options that
you would specify for docker build
:
# docker-bake.hcl
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
}
$ docker buildx bake webapp-dev
Note
In the case of compose files, each service corresponds to a target. If compose service name contains a dot it will be replaced with an underscore.
Complete list of valid target fields available for HCL and JSON definitions:
Name | Type | Description |
---|---|---|
inherits |
List | Inherit build options from other targets |
args |
Map | Set build-time variables (same as --build-arg flag) |
cache-from |
List | External cache sources (same as --cache-from flag) |
cache-to |
List | Cache export destinations (same as --cache-to flag) |
context |
String | Set of files located in the specified path or URL |
contexts |
Map | Additional build contexts (same as --build-context flag) |
dockerfile |
String | Name of the Dockerfile (same as --file flag) |
dockerfile-inline |
String | Inline Dockerfile content |
labels |
Map | Set metadata for an image (same as --label flag) |
no-cache |
Bool | Do not use cache when building the image (same as --no-cache flag) |
no-cache-filter |
List | Do not cache specified stages (same as --no-cache-filter flag) |
output |
List | Output destination (same as --output flag) |
platforms |
List | Set target platforms for build (same as --platform flag) |
pull |
Bool | Always attempt to pull all referenced images (same as --pull flag) |
secret |
List | Secret to expose to the build (same as --secret flag) |
ssh |
List | SSH agent socket or keys to expose to the build (same as --ssh flag) |
tags |
List | Name and optionally a tag in the format name:tag (same as --tag flag) |
target |
String | Set the target build stage to build (same as --target flag) |
Group
A group is a grouping of targets:
# docker-bake.hcl
group "build" {
targets = ["db", "webapp-dev"]
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
}
target "db" {
dockerfile = "Dockerfile.db"
tags = ["docker.io/username/db"]
}
$ docker buildx bake build
Variable
Similar to how Terraform provides a way to define variables, the HCL file format also supports variable block definitions. These can be used to define variables with values provided by the current environment, or a default value when unset:
# docker-bake.hcl
variable "TAG" {
default = "latest"
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:${TAG}"]
}
$ docker buildx bake webapp-dev # will use the default value "latest"
$ TAG=dev docker buildx bake webapp-dev # will use the TAG environment variable value
Tip
See also the Configuring builds page for advanced usage.
Functions
A set of generally useful functions provided by go-cty are available for use in HCL files:
# docker-bake.hcl
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
args = {
buildno = "${add(123, 1)}"
}
}
In addition, user defined functions are also supported:
# docker-bake.hcl
function "increment" {
params = [number]
result = number + 1
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
args = {
buildno = "${increment(123)}"
}
}
Note
See User defined HCL functions page for more details.
Built-in variables
BAKE_CMD_CONTEXT
can be used to access the maincontext
for bake command from a bake file that has been imported remotely.BAKE_LOCAL_PLATFORM
returns the current platform's default platform specification (e.g.linux/amd64
).
Merging and inheritance
Multiple files can include the same target and final build options will be determined by merging them together:
# docker-bake.hcl
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
}
# docker-bake2.hcl
target "webapp-dev" {
tags = ["docker.io/username/webapp:dev"]
}
$ docker buildx bake -f docker-bake.hcl -f docker-bake2.hcl webapp-dev
A group can specify its list of targets with the targets
option. A target can
inherit build options by setting the inherits
option to the list of targets or
groups to inherit from:
# docker-bake.hcl
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:${TAG}"]
}
target "webapp-release" {
inherits = ["webapp-dev"]
platforms = ["linux/amd64", "linux/arm64"]
}
default
target/group
When you invoke bake
you specify what targets/groups you want to build. If no
arguments is specified, the group/target named default
will be built:
# docker-bake.hcl
target "default" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
}
$ docker buildx bake
Definitions
HCL definition
HCL definition file is recommended as its experience is more aligned with buildx UX and also allows better code reuse, different target groups and extended features.
# docker-bake.hcl
variable "TAG" {
default = "latest"
}
group "default" {
targets = ["db", "webapp-dev"]
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:${TAG}"]
}
target "webapp-release" {
inherits = ["webapp-dev"]
platforms = ["linux/amd64", "linux/arm64"]
}
target "db" {
dockerfile = "Dockerfile.db"
tags = ["docker.io/username/db"]
}
JSON definition
{
"variable": {
"TAG": {
"default": "latest"
}
},
"group": {
"default": {
"targets": [
"db",
"webapp-dev"
]
}
},
"target": {
"webapp-dev": {
"dockerfile": "Dockerfile.webapp",
"tags": [
"docker.io/username/webapp:${TAG}"
]
},
"webapp-release": {
"inherits": [
"webapp-dev"
],
"platforms": [
"linux/amd64",
"linux/arm64"
]
},
"db": {
"dockerfile": "Dockerfile.db",
"tags": [
"docker.io/username/db"
]
}
}
}
Compose file
# docker-compose.yml
services:
webapp:
image: docker.io/username/webapp:latest
build:
dockerfile: Dockerfile.webapp
db:
image: docker.io/username/db
build:
dockerfile: Dockerfile.db
Note
See Building from Compose file page for more details.
Remote definition
You can also build bake files directly from a remote Git repository or HTTPS URL:
$ docker buildx bake "https://github.com/docker/cli.git#v20.10.11" --print
#1 [internal] load git source https://github.com/docker/cli.git#v20.10.11
#1 0.745 e8f1871b077b64bcb4a13334b7146492773769f7 refs/tags/v20.10.11
#1 2.022 From https://github.com/docker/cli
#1 2.022 * [new tag] v20.10.11 -> v20.10.11
#1 DONE 2.9s
{
"group": {
"default": {
"targets": [
"binary"
]
}
},
"target": {
"binary": {
"context": "https://github.com/docker/cli.git#v20.10.11",
"dockerfile": "Dockerfile",
"args": {
"BASE_VARIANT": "alpine",
"GO_STRIP": "",
"VERSION": ""
},
"target": "binary",
"platforms": [
"local"
],
"output": [
"build"
]
}
}
}
As you can see the context is fixed to https://github.com/docker/cli.git
even if
no context is actually defined
in the definition.
If you want to access the main context for bake command from a bake file
that has been imported remotely, you can use the BAKE_CMD_CONTEXT
built-in var.
$ cat https://raw.githubusercontent.com/tonistiigi/buildx/remote-test/docker-bake.hcl
target "default" {
context = BAKE_CMD_CONTEXT
dockerfile-inline = <<EOT
FROM alpine
WORKDIR /src
COPY . .
RUN ls -l && stop
EOT
}
$ docker buildx bake "https://github.com/tonistiigi/buildx.git#remote-test" --print
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile",
"dockerfile-inline": "FROM alpine\nWORKDIR /src\nCOPY . .\nRUN ls -l \u0026\u0026 stop\n"
}
}
}
$ touch foo bar
$ docker buildx bake "https://github.com/tonistiigi/buildx.git#remote-test"
...
> [4/4] RUN ls -l && stop:
#8 0.101 total 0
#8 0.102 -rw-r--r-- 1 root root 0 Jul 27 18:47 bar
#8 0.102 -rw-r--r-- 1 root root 0 Jul 27 18:47 foo
#8 0.102 /bin/sh: stop: not found
$ docker buildx bake "https://github.com/tonistiigi/buildx.git#remote-test" "https://github.com/docker/cli.git#v20.10.11" --print
#1 [internal] load git source https://github.com/tonistiigi/buildx.git#remote-test
#1 0.429 577303add004dd7efeb13434d69ea030d35f7888 refs/heads/remote-test
#1 CACHED
{
"target": {
"default": {
"context": "https://github.com/docker/cli.git#v20.10.11",
"dockerfile": "Dockerfile",
"dockerfile-inline": "FROM alpine\nWORKDIR /src\nCOPY . .\nRUN ls -l \u0026\u0026 stop\n"
}
}
}
$ docker buildx bake "https://github.com/tonistiigi/buildx.git#remote-test" "https://github.com/docker/cli.git#v20.10.11"
...
> [4/4] RUN ls -l && stop:
#8 0.136 drwxrwxrwx 5 root root 4096 Jul 27 18:31 kubernetes
#8 0.136 drwxrwxrwx 3 root root 4096 Jul 27 18:31 man
#8 0.136 drwxrwxrwx 2 root root 4096 Jul 27 18:31 opts
#8 0.136 -rw-rw-rw- 1 root root 1893 Jul 27 18:31 poule.yml
#8 0.136 drwxrwxrwx 7 root root 4096 Jul 27 18:31 scripts
#8 0.136 drwxrwxrwx 3 root root 4096 Jul 27 18:31 service
#8 0.136 drwxrwxrwx 2 root root 4096 Jul 27 18:31 templates
#8 0.136 drwxrwxrwx 10 root root 4096 Jul 27 18:31 vendor
#8 0.136 -rwxrwxrwx 1 root root 9620 Jul 27 18:31 vendor.conf
#8 0.136 /bin/sh: stop: not found