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.
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.