Docker Bake platform-specific adjustments

When building images, some platform-specific configurations are often required. For example, when working with uv, arm* builds require some flags to be set to prevent CPU thrashing during dependency installation.

How does one apply platform-specific changes to multiu-platform build stages in the Docker Bake HCL/yaml syntax?

You can use built-in variables:

https://github.com/docker/buildx/blob/master/docs/bake-reference.md#built-in-variables

The following variables are built-ins that you can use with Bake without having to define them.

Variable Description
BAKE_CMD_CONTEXT Holds the main context when building using a remote Bake file.
BAKE_LOCAL_PLATFORM Returns the current platform’s default platform specification (e.g. linux/amd64).

And there are variables in a Dockerfile

https://docs.docker.com/build/building/variables/#multi-platform-build-arguments

Then you can write conditions in scripts.

Is it what you were looking for?

This means I would ultimately need platform-specific logic within the Dockerfile itself - yes?

This can absolutely work. I was hoping to use the “magic” of Bake to do this if it allows, but if this is the only way, I don’t mind.

You have to implement the logic somewhere and even if you do it in a bake file, you would need to implement something in the Dockerfile to make it possible. For example you can use a build argument in a Dockerfile and use it in a command like:

FROM alpine:latest

ARG PLATFORM_FLAGS

RUN echo mycommand "$PLATFORM_FLAGS" --common-flag1 --common-flag2 > /command.txt

CMD ["cat", "/command.txt"]

Then you could have a docker-bake.hcl like:

target "default" {
  dockerfile = "Dockerfile"
  matrix = {
    platform = ["linux/amd64", "linux/arm64"]
  }
  name = "myapp-${replace(platform, "/", "-")}"
  platforms = [platform]
  tags = ["myapp-${platform}"]
  args = {
    PLATFORM_FLAGS = platform == "linux/arm64" ? "--arm64-cpu" : "--amd64-cpu"
  }
}

Build the images

docker buildx bake

and try:

Command:

docker run --rm --platform linux/amd64 myapp-linux/amd64

Output:

mycommand --amd64-cpu --common-flag1 --common-flag2

Command:

docker run --rm myapp-linux/arm64

Output:

mycommand --arm64-cpu --common-flag1 --common-flag2

You could also change the condition to rely on built in variables like BAKE_LOCAL_PLATFORM but it would not help on macOS while building linux container images, because the local platfomrm would be your client’s platfom

target "default" {
  dockerfile = "Dockerfile"
  tags = ["myapp"]
  args = {
    PLATFORM_FLAGS = BAKE_LOCAL_PLATFORM == "linux/arm64" ? "--arm64-cpu" : "--amd64-cpu ${BAKE_LOCAL_PLATFORM}"
  }
}

Output:

docker run --rm myapp

Output:

mycommand --amd64-cpu darwin/arm64/v8 --common-flag1 --common-flag2

I only added the env variable after amd64-cpu to see it in the output after it generated amd64 instead of arm64 to the command.