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/arm64
,linux/arm/v7
,windows/amd64
)TARGETOS
– OS component ofTARGETPLATFORM
(for examaple,linux
)TARGETARCH
– architecture component ofTARGETPLATFORM
(for example,amd64
,arm64
)TARGETVARIANT
– variant component ofTARGETPLATFORM
(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.