Overriding configurations
Bake supports loading build definitions from files, but sometimes you need even more flexibility to configure these definitions. For example, you might want to override an attribute when building in a particular environment or for a specific target.
The following list of attributes can be overridden:
args
cache-from
cache-to
context
dockerfile
labels
no-cache
output
platform
pull
secrets
ssh
tags
target
To override these attributes, you can use the following methods:
File overrides
You can load multiple Bake files that define build configurations for your targets. This is useful when you want to separate configurations into different files for better organization, or to conditionally override configurations based on which files are loaded.
Default file lookup
You can use the --file
or -f
flag to specify which files to load.
If you don't specify any files, Bake will use the following lookup order:
compose.yaml
compose.yml
docker-compose.yml
docker-compose.yaml
docker-bake.json
docker-bake.override.json
docker-bake.hcl
docker-bake.override.hcl
If more than one Bake file is found, all files are loaded and merged into a single definition. Files are merged according to the lookup order.
$ docker buildx bake bake --print
[+] Building 0.0s (1/1) FINISHED
=> [internal] load local bake definitions 0.0s
=> => reading compose.yaml 45B / 45B 0.0s
=> => reading docker-bake.hcl 113B / 113B 0.0s
=> => reading docker-bake.override.hcl 65B / 65B
If merged files contain duplicate attribute definitions, those definitions are either merged or overridden by the last occurrence, depending on the attribute.
Bake will attempt to load all of the files in the order they are found. If multiple files define the same target, attributes are either merged or overridden. In the case of overrides, the last one loaded takes precedence.
For example, given the following files:
variable "TAG" {
default = "foo"
}
target "default" {
tags = ["username/my-app:${TAG}"]
}
variable "TAG" {
default = "bar"
}
Since docker-bake.override.hcl
is loaded last in the default lookup order,
the TAG
variable is overridden with the value bar
.
$ docker buildx bake --print
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": ["username/my-app:bar"]
}
}
}
Manual file overrides
You can use the --file
flag to explicitly specify which files to load,
and use this as a way to conditionally apply override files.
For example, you can create a file that defines a set of configurations for a
specific environment, and load it only when building for that environment. The
following example shows how to load an override.hcl
file that sets the TAG
variable to bar
. The TAG
variable is then used in the default
target.
variable "TAG" {
default = "foo"
}
target "default" {
tags = ["username/my-app:${TAG}"]
}
variable "TAG" {
default = "bar"
}
Printing the build configuration without the --file
flag shows the TAG
variable is set to the default value foo
.
$ docker buildx bake --print
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": [
"username/my-app:foo"
]
}
}
}
Using the --file
flag to load the overrides.hcl
file overrides the TAG
variable with the value bar
.
$ docker buildx bake -f docker-bake.hcl -f overrides.hcl --print
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": [
"username/my-app:bar"
]
}
}
}
Command line
You can also override target configurations from the command line with the
--set
flag:
# docker-bake.hcl
target "app" {
args = {
mybuildarg = "foo"
}
}
$ docker buildx bake --set app.args.mybuildarg=bar --set app.platform=linux/arm64 app --print
{
"group": {
"default": {
"targets": ["app"]
}
},
"target": {
"app": {
"context": ".",
"dockerfile": "Dockerfile",
"args": {
"mybuildarg": "bar"
},
"platforms": ["linux/arm64"]
}
}
}
Pattern matching syntax defined in https://golang.org/pkg/path/#Match is also supported:
$ docker buildx bake --set foo*.args.mybuildarg=value # overrides build arg for all targets starting with "foo"
$ docker buildx bake --set *.platform=linux/arm64 # overrides platform for all targets
$ docker buildx bake --set foo*.no-cache # bypass caching only for targets starting with "foo"
Complete list of attributes that can be overridden with --set
are:
args
cache-from
cache-to
context
dockerfile
labels
no-cache
output
platform
pull
secrets
ssh
tags
target
Environment variables
You can also use environment variables to override configurations.
Bake lets you use environment variables to override the value of a variable
block. Only variable
blocks can be overridden with environment variables.
This means you need to define the variables in the bake file and then set the
environment variable with the same name to override it.
The following example shows how you can define a TAG
variable with a default
value in the Bake file, and override it with an environment variable.
variable "TAG" {
default = "latest"
}
target "default" {
context = "."
dockerfile = "Dockerfile"
tags = ["docker.io/username/webapp:${TAG}"]
}
$ export TAG=$(git rev-parse --short HEAD)
$ docker buildx bake --print webapp
The TAG
variable is overridden with the value of the environment variable,
which is the short commit hash generated by git rev-parse --short HEAD
.
{
"group": {
"default": {
"targets": ["webapp"]
}
},
"target": {
"webapp": {
"context": ".",
"dockerfile": "Dockerfile",
"tags": ["docker.io/username/webapp:985e9e9"]
}
}
}
Type coercion
Overriding non-string variables with environment variables is supported. Values passed as environment variables are coerced into suitable types first.
The following example defines a PORT
variable with a default value of 8080
.
The default
target uses a
ternary operator
to set the PORT
variable to the value of the environment variable PORT
if it is greater than 1024
, otherwise it uses the default value.
In this case, the PORT
variable is coerced to an integer before the ternary
operator is evaluated.
default_port = 8080
variable "PORT" {
default = default_port
}
target "default" {
args = {
PORT = PORT > 1024 ? PORT : default_port
}
}
Attempting to set the PORT
variable with a value less than 1024
will result
in the default value being used.
$ PORT=80 docker buildx bake --print
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile",
"args": {
"PORT": "8080"
}
}
}
}