Dockerfile Conditional FROM

Hello. I’m creating a multiarch docker image using buildx. In my Dockerfile, I’m wanting to set the FROM based on the TARGETARCH of the platform. For example:

ARG my_image
FROM my-image-arm64    #if TARGETARCH is arm64
or
FROM my-image-amd64   #if TARGETARCH is amd64

I’m currently passing in the my-image arg as a build-arg in the docker buildx build command. Is there a way to append the TARGETARCH to the build-arg? I know TARGETARCH is set automatically, but guessing I can’t modify the build arg after it’s been passed to the Dockerfile.

Thinking something like:

docker buildx build \
....
--build-arg my_image-${TARGETARCH}

Any help on this would be greatly appreciated.

Forgive me If I am too lazy to take the idea for a spindrive, though I’d like to share some thoughts.
You already use an ARG instruction to pass over the image name in combination with a --build-arg argument.

NB: Declaring an ARG instruction to be used for a FROM instruction is perfact valid, and can only be used for the FROM instruction.

I understand that ${TARGETARCH} is a variable automaticly available in the Dockerfile context.

Thus said, have you tried:

ARG MY_IMAGE
FROM ${MY_IMAGE}-${TARGETARCH}
...

And then build it using: docker buildx build --build-arg MY_IMAGE=my_image ...

The variable ${TARGETARCH} won’t be available on the shell where you run docker buildx build .. as such you draft can’t work, except when you set the variable before yourself.

Thanks for the reply! Yes, I initially tried that, but it didn’t seem to display the ${TARGETARCH}. I get a message saying

Dockerfile:7
--------------------
   4 |     ARG MYIMAGE
   5 |     ARG TARGETARCH
   6 |    
   7 | >>> FROM ${MYIMAGE}-${TARGETARCH}
   8 |    
   9 |     RUN echo "I'm building for $TARGETARCH"
--------------------
error failed to solve: my_image:1.0.0- is not found.

I looked around and found that the TARGETARCH is automatically set in the FROM scope. So after removing the ARG TARGETARCH from the Dockerfile I see the TARGETARCH appended to MYIMAGE, but the issue now (and realized I didn’t mention in initial post) is that MYIMAGE is actually created with a version.

I am pulling the value of MYIMAGE from a different source, so in my build-arg it is actually my_image:1.0.0. With the above solution it would actually add the TARGETARCH to the end and make MYIMAGE be my-image:1.0.0-arm64 which will not match what I’m wanting which is my-image-arm64:1.0.0. Is there a way to display the TARGETARCH before the version?

What I’m thinking is that I would have to pull the MYIMAGE value from the source, do some type of manipulation on the value to break it into multiple values and then pass each one as a build arg like:
docker buildx build --build-arg MY_IMAGE=name --build-arg VERSION=version ... and then in the Dockerfile have: FROM ${MY_IMAGE}:${VERSION}-${TARGETARCH}. Is there any other way to do this as I would prefer to only pass in one build-arg?

I am afraid this can not be done just inside the Dockerfile.

I am also uncertain, if it is even possible to add more than one ARG before the FROM part - never actualy tried it with more then a single ARG yet.

What you try will only work if it’s actualy possible to use more than a single arg. Otherwise you will need to prepare the final ${repo}:{tag} (as in my-image-arm64:1.0.0) and assign it to a single build-arg yourself.

I suppose the name before the version tag does not change often. You can use a default value for the argument so you can use one argument in the most cases.

ARG MYIMAGE=defaultvalue
ARG VERSION
FROM ${MYIMAGE}:${TARGETARCH}-${VERSION:?}

In this case “VERSION is not allowed to be empty” due to the colon and the question mark but the other argument is optional.

docker buildx build . --build-arg VERSION=1.0.0

If you don’t like it then the only solution is using a small script outside the Dockerfile to build the argument as @meyay already mentioned.

It is. Dockerfile reference | Docker Docs

FROM may only be preceded by one or more ARG instructions,