Docker Bake platform-specific adjustments

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.