Build multi-arch docker images

How to build container images for multi-arch support.

Published on October 4, 21

Synpse is an end-to-end platform to manage your device fleet that can grow to hundreds of thousands of devices, perform OTA software updates, collect metrics, logs, deploy your containerized applications and facilitate tunnel-based SSH access to any of your device. You can find a Quick Start here .


There is quite a few blogs around how to build multi-arch docker images. We found most of them bit complicated and confusing. Here is our version of “complicated”. With languages like Go it is easy. but not this is the case for non-compiled languages like Python. For them all supporting libraries must be there.

Multi-arch images

You can build multi-arch images multiple ways. Most popular are:

  • Use a separate tags (image:arm64, image:amd64). Easy to understand and consume. Downside of this approach is that applications deployed on the platforms like Synpse will require different image names, if same application spans different devices. Ontop of this you might find that you need to build images on the devices with specific architectures itself.
  • Use docker buildx. This command allows to use built-in multi-arch builders from docker. It will produce single image with multi-arch manifest. It can be seen in the registry itself or by inspecting image. This will present as single image and can be used on multiple devices.

Quay multi-arch
Quay multi-arch

Lets use second method to build images:

  1. Install emulators:
1
2
3
4
5
# install emulators (https://github.com/tonistiigi/binfmt)
docker run --privileged --rm tonistiigi/binfmt --install all
docker run --privileged --rm tonistiigi/binfmt --install arm64,riscv64,arm
# activate builder
docker buildx create --use
  1. Run a build command for single dockerfile:
1
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t image:latest --push -f Dockerfile .

Our dockerfile is quite simple:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
FROM python:3.8.12-bullseye

WORKDIR /server

RUN apt-get -y update && \
    apt-get install software-properties-common -y && \
    add-apt-repository ppa:george-edison55/cmake-3.x -y && \
    apt-get install cmake -y

COPY ./gateway/requirements.txt requirements.txt
RUN pip install -r requirements.txt

COPY . .

RUN chmod 777 /server/gateway/aws.py

ENTRYPOINT [ "python" ]
CMD [ "/server/gateway/aws.py" ]

Important note: Some architectures might require different OS level packages, so what works on ARM64 might not work on ARM32. Build time for 32 bit architecture images will take much longer too, .

Important: Sometimes builds goes “bananas up”. So you might need to reset the builder docker run --rm --privileged multiarch/qemu-user-static --reset -p and reinstall it. More about this https://github.com/tonistiigi/binfmt#uninstalling-emulators.

./wrap_up.sh

Having same image supporting multi-arch is very convenient when you use platforms like Synpse, where your applications can span multiple architectures on a multiple devices.

If you have any questions or suggestions, feel free to start a new discussion in our forum or drop us a line on Discord