Docker Crossbuilds: Platform Sensitive Dockerfile Commands

Whilst it’s true to a certain extent that Docker containers “run anywhere”, that “anywhere” comes with a proviso: Docker images are built for particular operating system architectures. A wide variety of machines run amd64 processor instruction sets, but other devices, such as the new Mac M1 processor based machines, are arm64 devices; and Raspberry Pi’s can run as either arm64 or arm/v7 (32 bit).

A single Dockerfile can be used to build images for each architecture using build commands of the form:

docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64 .

In some cases, you may need to modify the Dockerfile to perform slightly different actions based on the architecture type. Several arguments are available in the Dockerfile (brought into scope by declaring them using ARG) that allow you to modify behaviour based on the the architecture:

  • TARGETPLATFORM – platform of the build result (for example, linux/amd64, linux/arm64linux/arm/v7windows/amd64)
  • TARGETOS – OS component of TARGETPLATFORM (for examaple, linux)
  • TARGETARCH – architecture component of TARGETPLATFORM (for example, amd64, arm64 )
  • TARGETVARIANT – variant component of TARGETPLATFORM (for example, v7)

In a Dockerfile, we might then have something like:

ARG TARGETPLATFORM

...

# RUN command for specific target platforms
RUN if [ "$TARGETPLATFORM" = "linux/amd64" ] || ["$TARGETPLATFORM" = "linux/arm64"] ; \
    then MPLBACKEND=Agg python3 -c "import matplotlib.pyplot" &>/dev/null ; fi 

For more discussion and examples, see WIP: Docker –platform translation example for TARGETPLATFORM.

Author: Tony Hirst

I'm a Senior Lecturer at The Open University, with an interest in #opendata policy and practice, as well as general web tinkering...

%d bloggers like this: