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.
To override target attributes or the variables used to configure them, use:
File overrides
CLI overrides
Variable overrides
Environment variable overrides
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.hcl
docker-bake.override.json
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 --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.arg.mybuildarg=bar \
    --set app.platform=linux/arm64 app --print
{
  "group": {
    "default": {
      "targets": ["app"]
    }
  },
  "target": {
    "app": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "args": {
        "mybuildarg": "bar"
      },
      "platforms": ["linux/arm64"]
    }
  }
}
[!NOTE]
--set is a repeatable flag. For array fields such as 
tag, repeat 
--set
to provide multiple values or use 
+= to append without replacing.
An empty assignment, such as 
--set app.tag=, clears the array. Subsequent
assignments add values to the cleared array. Array literal syntax such as
--set app.tag=[a,b] is not supported.
Override keys use singular names such as 
arg, 
secret, and 
tag. These
names apply to 
--set selectors; Bake file attributes keep their existing
names, such as 
args and 
tags. Older plural override spellings remain
supported as aliases.
context and 
contexts aren't aliases: 
context sets the main build
context, while 
contexts.<name> sets one named context. The alias 
secrets
applies to the secret list override only; 
secrets.<id> is invalid.
You can match multiple targets with a pattern. Quote the override so your
shell doesn't expand the pattern before Bake reads it:
$ docker buildx bake --set 'foo*.arg.mybuildarg=value'
$ docker buildx bake --set '*.platform=linux/arm64'
$ docker buildx bake --set 'foo*.no-cache'
The first and third commands affect targets whose names start with 
foo.
The second sets the platform for all targets. For the full list of override
keys, aliases, pattern syntax, and fields supporting 
+=, see the
--set reference.
Override list attributes
Attributes such as 
secret, 
ssh, and 
output can use lists of objects in a
Bake file. In a 
--set value, use the inline syntax of the corresponding
build flag, rather than an HCL object or array. For example, 
secret uses the
same 
id=...,src=... syntax as
build --secret.
Use 
= to replace the secret list, 
+= to add a secret, or an empty value
to clear the list:
$ docker buildx bake --set app.secret=id=aws,src=./credentials app
$ docker buildx bake --set app.secret+=id=gcp,env=GCP_CREDENTIALS app
$ docker buildx bake --set app.secret= app
These operations affect the list as a whole. To change only the source of one
declared secret while preserving the others, use 
secret.<id>.
Override a secret source
Use 
--set <target>.secret.<id>=<source> to change the source of an existing
secret without replacing the target's secret list. The secret ID must already
be declared by the target.
For example, declare an 
aws secret in the Bake file:
target "app" {
  secret = [{
    id  = "aws"
    src = "./credentials"
  }]
}
Supply its value from an environment variable or a different file:
$ docker buildx bake --set app.secret.aws=env=AWS_CREDENTIALS app
$ docker buildx bake --set app.secret.aws=src=/path/to/credentials app
The build still receives the secret as 
aws. Other declared secrets keep
their sources. The override fails if the target doesn't declare 
aws, or if
an 
id= in the override value names a different secret. This form doesn't
support 
+=.
Named source overrides are applied after secret list overrides, so the ID
must exist in the resulting list. The value describes the complete source
using 
env=... or 
src=...; it doesn't address an object field such as
secret.aws.env.
Override resource limits
Use 
--set <target>.resource.<name>=<value> to change a resource limit for
the containers that run build steps. For example, override memory and CPU
limits for an 
app target:
$ docker buildx bake --set app.resource.memory=2g \
    --set app.resource.cpu-quota=50000 app
Supported names are 
memory, 
memory-swap, 
cpu-shares, 
cpu-period,
cpu-quota, 
cpuset-cpus, and 
cpuset-mems. Each override changes only the
named limit, preserving other limits from the Bake definition. Resource
overrides don't support 
+=.
These limits require a BuildKit daemon with per-step resource limit support
and take effect on Linux. They control resources within a build step, rather
than how many Bake targets run concurrently. See the
--resource reference for
units and supported values, and the
resources attribute for file configuration.
Variables
Use 
--var NAME=value to override a declared Bake variable for a single
invocation. For example, set 
TAG without exporting it in your shell:
$ docker buildx bake --var TAG=dev webapp
The value takes precedence over an environment variable with the same name.
Unlike 
--set webapp.tags=..., this changes the variable wherever the Bake
definition uses it. See
Override variable values for
precedence, types, and repeated flags.
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.
To disable these lookups, set 
BUILDX_BAKE_DISABLE_VARS_ENV_LOOKUP=1; see the
variable reference.
You can still provide variable values explicitly with 
--var NAME=value.
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. The 
backend target uses the
PORT variable as-is, and the 
frontend target uses the value of 
PORT
incremented by one.
variable "PORT" {
  default = 3000
}
group "default" {
  targets = ["backend", "frontend"]
}
target "backend" {
  args = {
    PORT = PORT
  }
}
target "frontend" {
  args = {
    PORT = add(PORT, 1)
  }
}
Overriding 
PORT using an environment variable will first coerce the value
into the expected type, an integer, before the expression in the 
frontend
target runs.
$ PORT=7070 docker buildx bake --print
{
  "group": {
    "default": {
      "targets": [
        "backend",
        "frontend"
      ]
    }
  },
  "target": {
    "backend": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "args": {
        "PORT": "7070"
      }
    },
    "frontend": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "args": {
        "PORT": "7071"
      }
    }
  }
}