Skip to content

Instantly share code, notes, and snippets.

@Makeshift
Created April 1, 2023 23:40
Show Gist options
  • Save Makeshift/c9934ba604f6452e7510f84ce14566d9 to your computer and use it in GitHub Desktop.
Save Makeshift/c9934ba604f6452e7510f84ce14566d9 to your computer and use it in GitHub Desktop.
What's MYTARGETARCH and why are you using it?

You might see this style of multi-arch binary management in a few Dockerfiles that I maintain:

ARG TARGETARCH
ARG MYTARGETARCH="${TARGETARCH:-amd64}"

ARG MICROMAMBA_amd64_URL="https://micro.mamba.pm/api/micromamba/linux-64/latest"
ARG MICROMAMBA_arm64_URL="https://micro.mamba.pm/api/micromamba/linux-aarch64/latest"

RUN MICROMAMBA_URL_STR="MICROMAMBA_${MYTARGETARCH}_URL" && MICROMAMBA_URL="${!MICROMAMBA_URL_STR}" \
    && curl -L "${MICROMAMBA_URL}" | tar -xvj bin/micromamba \
    ...

I'm quite fond of this particular style of handling multi-architecture Dockerfiles, because of a weird quirk with how Buildx interacts with the TARGETARCH variable (and also it makes grabbing prebuilt binaries for multiple arch's easier). Here's an explanation for why:

# This should be populated on-build with buildkit. If you aren't using buildkit, it'll be ignored and your image will be built using whatever architecture you're using, and MYTARGETARCH will default to amd64.
# These are defaults and can/will be overridden by the buildkit build args.
# Don't override TARGETARCH, it's for buildkit only and you'll mess up the build.
# TARGETARCH will equal "amd64" or "arm64" depending on what we're targetting (these are the two
#  architectures our base image supports properly at the moment)
ARG TARGETARCH
# This exists because TARGETARCH isn't a normal build ARG.
# With normal build args, if you set them in the Dockerfile they're considered "default" values, and
#  if you set them in your build command they'll override the default value.
# However, with TARGETARCH et al, if you set them in the Dockerfile THEY override buildkit's provided values,
#  which then changes the target architecture for the rest of your build. This is bad, and will usually result in non-workng images.
ARG MYTARGETARCH="${TARGETARCH:-amd64}"

If you're targetting more than like 3 architectures, it becomes more tedious to try and maintain many URLs in your Dockerfile. It becomes even more annoying if you're targetting an architecture that doesn't have prebuilt binaries for the tool you want. At that point, I'd advise abandoning this strategy and just building the tool directly in the container.

Until then, though - this is a nice little way of handling 2-3 architectures, not getting in the way of buildkit doing its thing, and making sure each image has the right architecture tooling.

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