moby / moby/buildkit

`FROM --platform=$BUILDPLATFORM a as b` not overriding `TARGETPLATFORM` for multi-stage builds

Open
#4,929 11 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

kind/duplicate kind/question
Dominant language
Go
Stars
10.3k
Forks
1.5k
Avg merge
1d 23h
Merged PRs (30d)
48

Description

I'm currently investing in making our builds cross-platorm compatible. I want to e.g. download the uv package manager and use it in both our build and target images. I then hit the following issue, when trying to keep our build instructions DRY:

FROM busybox as base
ARG TARGETPLATFORM
RUN echo $TARGETPLATFORM > /plt
FROM --platform=$TARGETPLATFORM base as base-target
FROM --platform=$BUILDPLATFORM base as base-build

I would expect this to build two different variants of the base stage when BUILD!=TARGET, one for each. Like this works for multi platform images pulled from the registry. But this is not the case:

#On linux/amd64:
$ docker build --platform=linux/arm64 -f test.Dockerfile --target=base-build .
...
 => CACHED [base 2/2] RUN echo linux/arm64 > /plt
...
$ docker build --platform=linux/arm64 -f test.Dockerfile --target=base-target .
...
 => CACHED [base 2/2] RUN echo linux/arm64 > /plt
...
FROM --platform=$TARGETPLATFORM alpine as base-target
FROM --platform=$BUILDPLATFORM alpine as base-build

Here's the different behavior with images from the registry:

$ docker build --platform=linux/arm64 -f test.Dockerfile --target=base-build -t target .
$ docker run --rm -it target cat /etc/apk/arch
aarch64
$ docker build --platform=linux/arm64 -f test.Dockerfile --target=base-build -t build .
$ docker run --rm -it build cat /etc/apk/arch
x86_64

It seems like there's no other way to get this working besides duplicating the base stage for the different platforms and giving them a unique stage name. I'm happy to hear any other workarounds.

Possibly related to

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the two builds from the issue with the provided test.Dockerfile, comparing the local base stage with the registry-image behavior. Review the related issue #4237 and BuildKit's multi-stage platform handling. Done means --platform=$BUILDPLATFORM and --platform=$TARGETPLATFORM produce the expected distinct variants without duplicating the base stage.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, dockerfile
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.