LewlSauce
LewlSauce

Reputation: 5872

Building a multi-architecture Docker image, but Dockerfile requires different packages depending on architecture

I am experimenting with docker's buildx and noticed that everything seems to be straight forward except for one thing. My Dockerfile needs to pull certain packages depending on the architecture.

For example, here's a piece of the Dockerfile:

FROM XYZ

# Set environment variable for non-interactive install
ARG DEBIAN_FRONTEND=noninteractive

# Run basic commands to update the image and install basic stuff.
RUN apt update && \
    apt dist-upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" && \
    apt autoremove -y && \
    apt clean -y && \
    ...
    # Install amazon-ssm-agent
    mkdir /tmp/ssm && \
    curl https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb -o /tmp/ssm/amazon-ssm-agent.deb && \ 

As you can see from above, the command is set to pull down the Amazon SSM agent using a hard-coded link.

What's the best way to approach this? Should I just modify this Dockerfile to create a bunch of if conditions?

Upvotes: 1

Views: 3170

Answers (1)

David Maze
David Maze

Reputation: 158908

Docker automatically defines a set of ARGs for you when you're using the BuildKit backend (which is now the default). You need to declare that ARG, and then (within the RUN command) you can use an environment variable $TARGETOS to refer to the target operating system (the documentation suggests linux or windows).

FROM ...
# Must be explicitly declared, and after FROM
ARG TARGETOS
# Then it can be used like a normal environment variable
RUN curl https://s3.amazonaws.com/ec2-downloads-$TARGETOS/...

There is a similar $TARGETPLATFORM if you need to build either x86 or ARM images, but its syntax doesn't necessarily match what's in this URL. If $TARGETPLATFORM is either amd64 or arm, you may need to reconstruct the Debian architecture string. You can set a shell variable within a single RUN command and it will last until the end of that command, but no longer.

ARG TARGETPLATFORM
RUN DEBARCH="$TARGETPLATFORM"; \
    if [ "$DEBARCH" = "arm" ]; then DEBARCH=arm64; fi; \
    curl .../debian-$DEBARCH/...

Upvotes: 7

Related Questions