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

Use ARG in stage name #2618

Open
Bidski opened this issue Feb 11, 2022 · 8 comments
Open

Use ARG in stage name #2618

Bidski opened this issue Feb 11, 2022 · 8 comments

Comments

@Bidski
Copy link

Bidski commented Feb 11, 2022

Is it possible to do something like this?

ARG variant

FROM archlinux:latest AS base-image
RUN some things

FROM base-image AS base-image-${variant}
RUN some variant specific things

FROM base-image-${variant} AS base-image-${variant}-sub-image-1
RUN some more things

FROM base-image-${variant} AS base-image-${variant}-sub-image-2
RUN some more things

I have seen recommendation on to use

ARG variant 

FROM archlinux:latest AS base-image
RUN some things

FROM base-image AS base-image-generic
RUN some variant specific things

FROM base-image AS base-image-not-generic
RUN some variant specific things

FROM base-image-${variant}
RUN some more things

However I have quite a few sub-images and at least 3 variants. So I would have to duplicate every single stage at least 3 times in order to make this work. This is extremely undesirable as it is just duplicating code and making maintaining it almost impossible.

@tonistiigi
Copy link
Member

I don't quite understand how this helps you. An arg can only have one single value for the whole build, so essentially the value in the stage name is a constant.

You never need to duplicate code when you are making more cases like this. You only need to add new FROM statements that point to already defined stage. A stage can be just the FROM command.

For the way how to avoid defining FROM for each condition if they are the same we will probably go with #2389 #1772 .

@Bidski
Copy link
Author

Bidski commented Feb 11, 2022

I guess this might be a misunderstanding on my part with how stages work then. Does each stage effectively create an image? (as in if I run docker image ls after building everything will all of the stages be listed there?)

If so, then the arg will result in the creation of different images with different names and will prevent incompatible images being used as a cache in the build process.

@tonistiigi
Copy link
Member

Does each stage effectively create an image?

No. Each build creates one result (that can be an image). Also, a stage name is not an image name.

Combining is done in higher-level tools, eg. https://github.com/docker/buildx/blob/master/docs/reference/buildx_bake.md

@Bidski
Copy link
Author

Bidski commented Feb 11, 2022

How does caching work on stages then?

@tonistiigi
Copy link
Member

How does caching work on stages then?

The issue tracker is not a good place for a broad question like this.

@Bidski
Copy link
Author

Bidski commented Feb 11, 2022

Where is a suitable place?

@tonistiigi
Copy link
Member

Stackoverflow, github discussions, #buildkit on slack

@thaJeztah
Copy link
Member

thaJeztah commented Dec 2, 2022

This came up recently while I was reviewing a pull-request in moby/moby#44513 (comment), and I have a use-case for this (combined with #3352).

In the moby repository we have some build-stages that should only be executed on specific architectures. For all other architectures, the stage should be a "no-op". To implement that, we're adding "stub" / "dummy" stages for each of those architectures; simplified, this looks like:

# dummy stages for unsupported platforms
FROM scratch AS build-windows-amd64
FROM scratch AS build-windows-arm64
FROM scratch AS build-linux-arm
FROM scratch AS build-linux-amd64
FROM scratch AS build-linux-ppc64le
FROM scratch AS build-linux-i386
FROM scratch AS build-linux-arm64
FROM scratch AS build-linux-riscv

# only supported on linux/amd64
FROM alpine AS build-linux-amd64
RUN echo "do some actual stuff"

FROM build-${TARGETOS}-${TARGETARCH} AS build

# ....
# ....
# ....

FROM baseimage AS final
COPY --from=build /. /bin/

As can be seen, this leads to a lot of boilerplating / repetition, and requires a dummy for each possible os/arch combination that isn't supported, which is error-prone.

If AS would allow for an ARG to be used, we can (combined with #3352, which looks to be supported) use the TARGETOS and TARGETARCH options to automatically create a dummy stage for "whichever" platform is used as target;

# dummy stage for any unsupported platform
FROM scratch AS build-${TARGETOS}-${TARGETARCH}

# only supported on linux/amd64
FROM alpine AS build-linux-amd64
RUN echo "do some actual stuff"

FROM build-${TARGETOS}-${TARGETARCH} AS build

# ....
# ....
# ....

FROM baseimage AS final
COPY --from=build /. /bin/

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

No branches or pull requests

4 participants