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.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.