Check architecture in dockerfile to get amd/arm
Asked Answered
M

2

24

We're working with Windows and Mac M1 machines to develop locally using Docker and need to fetch and install a .deb package within our docker environment.

The package needs amd64/arm64 depending on the architecture being used.

Is there a way to determine this in the docker file i.e.

if xyz === 'arm64'
    RUN wget http://...../arm64.deb
else 
    RUN wget http://...../amd64.deb
Mahoney answered 15/12, 2021 at 19:33 Comment(0)
F
24

First you need to check if there is no other (easier) way to do it with the package manager.

You can use the arch command to get the architecture (equivalent to uname -m). The problem is that it does not return the values you expect (aarch64 instead of arm64 and x86_64 instead of amd64). So you have to convert it, I have done it through a sed.

RUN arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) && \
    wget "http://...../${arch}.deb"

Note: You should add the following code before running this command to prevent unexpected behavior in case of failure in the piping chain. See Hadolint DL4006 for more information.

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
Forehanded answered 15/12, 2021 at 20:5 Comment(1)
This is great stuff. Works like a charm, I'll give it a whirl on Windows tomorrow but works perfectly on arm. Thanks a bunch.Mahoney
E
3

Later versions of Docker expose info about the current architecture using global variables:

BUILDPLATFORM — matches the current machine. (e.g. linux/amd64)
BUILDOS — os component of BUILDPLATFORM, e.g. linux
BUILDARCH — e.g. amd64, arm64, riscv64
BUILDVARIANT — used to set ARM variant, e.g. v7
TARGETPLATFORM — The value set with --platform flag on build
TARGETOS - OS component from --platform, e.g. linux
TARGETARCH - Architecture from --platform, e.g. arm64
TARGETVARIANT

Note that you may need to export DOCKER_BUILDKIT=1 on headless machines for these to work, and they are enabled by default on Docker Desktop.

Use in conditional scripts like so:

RUN wget "http://...../${TARGETARCH}.deb"

You can even branch Dockerfiles by using ONBUILD like this:

FROM alpine as build_amd
# Intel stuff goes here
ONBUILD RUN apt-get install -y intel_software.deb

FROM alpine as build_arm
# ARM stuff goes here
ONBUILD RUN apt-get install -y arm_software.deb

# choose the build to use for the rest of the image
FROM build_${TARGETARCH}
# rest of the dockerfile follows
Emancipation answered 3/2, 2023 at 1:26 Comment(1)
"These arguments are useful for doing cross-compilation in multi-platform builds. They're available in the global scope of the Dockerfile, but they aren't automatically inherited by build stages. To use them inside stage, you must declare them" i.e. ARG TARGETARCH docs.docker.com/build/building/variablesKristelkristen

© 2022 - 2024 — McMap. All rights reserved.