Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default value on TARGETPLATFORM always overrides #510

Open
MarcelWaldvogel opened this issue Jan 17, 2021 · 7 comments
Open

Default value on TARGETPLATFORM always overrides #510

MarcelWaldvogel opened this issue Jan 17, 2021 · 7 comments

Comments

@MarcelWaldvogel
Copy link

What I want to achieve

I have a project that I want to be able to build both with docker build (for compatibility) and docker buildx --platform and which requires TARGETPLATFORM to make a difference in the build process. As TARGETPLATFORM is not set by docker build, the default value option to ARG seemed the right choice.

What I expect

Given the following Dockerfile,

FROM debian:buster-slim
ARG TARGETPLATFORM=linux/amd64
RUN echo $TARGETPLATFORM; exit 1

I expect docker build . on all architectures to output linux/amd64 (the legacy compatibility case).

When running docker buildx --builder docker-multiarch --platform linux/386 ., the output should be linux/386.

What I get

On platform linux/amd64, docker buildx --builder docker-multiarch --platform linux/386 ., outputs linux/amd64 instead of linux/386.

Removing the default value solves this: docker buildx --builder docker-multiarch --platform linux/386 . results in linux/386 with Dockerfile:

FROM debian:buster-slim
ARG TARGETPLATFORM
RUN echo $TARGETPLATFORM; exit 1

However, docker build . results in an empty/undefined TARGETPLATFORM.

(For ARGs set with --build-arg on the command line, defaults behave as expected.)

System setup

  • Ubuntu 20.10
  • Docker 19.03.13
  • Buildx 0.4.1 or 0.5.1 (tested with both)

Workaround

The following Dockerfile results in the expected behavior:

FROM debian:buster-slim
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
RUN echo $TARGETPLATFORM; exit 1

However, this (a) defeats the purpose of the default value and (b) causes endless debugging sessions, as it violates the documentation of ARG and TARGETPLATFORM.

@tonistiigi
Copy link
Member

For the builtin args, default value is set if none is set by the user. For your use case it makes sense to overwrite the user's default value but for some others that want to fix TARGETPLATFORM for a specific value for a specific Dockerfile stage it is not. Current logic is more constant to the regular ARG behavior and not a special exception. And as you say, there is a workaround for setting the value if it is empty (for non-buildkit builders).

@MarcelWaldvogel
Copy link
Author

For the user it is not obvious that (a) TARGETPLATFORM and BUILDPLATFORM are only defaults, not actual values, (b) that explicit defaults override the implicit ones, and (c) that this type of workaround is needed/possible.

As I take your response as "WONTFIX: works as designed", how about changing the documentation to add the following (as there are no footnotes in Markdown, something along the following lines should be placed right before "High-level build options"):


Backward compatibility

Sometimes, backward compatibility of the build process to docker build needs to be preserved while differentiating on TARGETPLATFORM or BUILDPLATFORM for docker buildx. The seemingly obvious way of using defaults (e.g., ARG TARGETPLATFORM=linux/amd64) does not work, as the values set by docker buildx are already treated like defaults internally. The following construct is recommended as a workaround for these cases:

ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}

@tonistiigi
Copy link
Member

Yes, docs can always be improved (via PR). If you look at the current docs https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope it is defined that these parameters are defined in the global scope and global scope working like this is already documented.

We don't want to spend that much time describing what happens on other builders that users shouldn't care about but just encourage them to update. But adding a line reminding people that ${TARGETPLATFORM:-linux/amd64} can be used in place of the variable if you worry that Dockerfile might be run on a builder without this feature seems harmless.

@MarcelWaldvogel
Copy link
Author

I tried to shorten the explanation as much as possible. I hope it meets your expectations.

@crazy-max crazy-max added the docs label Jun 29, 2021
glimchb added a commit to glimchb/opi-poc that referenced this issue Aug 4, 2022
See docker/buildx#510

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
glimchb added a commit to glimchb/opi-poc that referenced this issue Aug 5, 2022
Fixes opiproject#163

See docker/buildx#510

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
glimchb added a commit to glimchb/opi-poc that referenced this issue Aug 8, 2022
Fixes opiproject#163

See docker/buildx#510

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
glimchb added a commit to glimchb/opi-poc that referenced this issue Aug 8, 2022
Fixes opiproject#163

See docker/buildx#510

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
glimchb added a commit to glimchb/opi-poc that referenced this issue Aug 8, 2022
Fixes opiproject#163

See docker/buildx#510

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
glimchb added a commit to glimchb/opi-poc that referenced this issue Aug 8, 2022
Fixes opiproject#163

See docker/buildx#510

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
glimchb added a commit to glimchb/opi-poc that referenced this issue Aug 8, 2022
Fixes opiproject#163

See docker/buildx#510

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
glimchb added a commit to glimchb/opi-poc that referenced this issue Aug 8, 2022
Fixes opiproject#163

See docker/buildx#510

Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com>
e0ne added a commit to e0ne/network-operator that referenced this issue Jan 8, 2024
This patch contains workaround to have the same Dockerfile for
`docker build` and `docker buildx` described at [1].

[1] docker/buildx#510

Signed-off-by: Ivan Kolodiazhnyi <ikolodiazhny@nvidia.com>
e0ne added a commit to e0ne/network-operator that referenced this issue Jan 8, 2024
This patch contains workaround to have the same Dockerfile for
`docker build` and `docker buildx` described at [1].

[1] docker/buildx#510

Signed-off-by: Ivan Kolodiazhnyi <ikolodiazhny@nvidia.com>
@cenkalti
Copy link

I've spent hours trying the solve an issue caused by this.

When I set a default value on an ARG, I expect it to be overriden by docker buildx build --platform= command.

If this is not fixable please add a note to the documentation so others can avoid falling the same trap.

@tonistiigi
Copy link
Member

When I set a default value on an ARG, I expect it to be overriden by docker buildx build --platform= command.

When you set default value on an ARG, you can expect it to be overridden by docker buildx build --build-arg ... command.

The following Dockerfile results in the expected behavior:
FROM debian:buster-slim
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
RUN echo $TARGETPLATFORM; exit 1

For clarity, "-linux/amd64" in that Dockerfile never gets called or has any impact on buildkit-based builder, no matter what configuration was passed to the build.

@cenkalti
Copy link

Sorry, I forgot to mention. I am talking specifically about TARGETOS and TARGETARCH args.

For example, if there is default value set on TARGETARCH, it doesn't matter what I pass in --platform and always the default value is used.

FROM debian:buster-slim
ARG TARGETARCH=amd64
RUN echo $TARGETARCH; exit 1
$ docker build --platform linux/arm64 .
...
 > [2/2] RUN echo amd64; exit 1:

If I remove the default value, it works as expected.

FROM debian:buster-slim
ARG TARGETARCH
RUN echo $TARGETARCH; exit 1
$ docker build --platform linux/arm64 .
...
 > [2/2] RUN echo arm64; exit 1:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants