Skip to content

Multiarch setups with QEMU

mviereck edited this page Sep 8, 2020 · 15 revisions

Multi-arch setups with QEMU

By default Docker can only run images that have the same architecture as the host. Most widespread are amd64 images running on amd64 hosts. With a regular setup it is not possible to run e.g. images with an arm/aarch64 architecture on amd64.

  • You can check the image architecture with docker inspect --format {{.Architecture}} IMAGENAME.
  • You can check the host architecture with uname -m.

However, with some setup it is possible to run arm/aarch64 images on amd64 and vice versa. Same goes for some other architectures. This is out of scope for x11docker that just want to provide an X server and some extra features, but of interest for multi-arch GUI development with the help of x11docker. x11docker itself does not care for the architecture, this is up to Docker and its configuration. This article just wants to point where to look further.

List of architectures supported by Docker.

QEMU

QEMU allows executing foreign architectures through dynamic translation of the instructions. Combining QEMU and Docker, it is possible to execute containers for e.g. ARM on AMD64, or vice versa. It can be either installed and configured on the host, or its kernel features can be enabled without an installation using dbhi/qus. An additional multi-arch building tool is buildx.

QEMU is installed and enabled in Docker Desktop by default. Hence, Windows/MacOS users can execute arm32v7 or arm64v8 images on their amd64 hosts, without any setup.

dbhi/qus

The main usage of dbhi/qus is to avoid installing a full QEMU package through package managers. It allows registering the foreign architectures you need, and no more. Any regular install would setup all the foreign architectures by default.

A shortcut to allow multiple archtitectures without installing QEMU on host is docker run --rm --privileged aptman/qus -s -- -p. This container adds some QEMU features to the host kernel. Technically, it uses a shell script to register binfmt interpreters based on the magic strings from QEMU, and point them to QEMU user static binaries. After executing that command, any foreign binary can be used on the host as long as it is statically built, or foreign dependencies exist. Precisely, using foreign containers avoids installing cross-platform toolchains.

Find detailed explanations, utilities and examples at dbhi/qus. Moreover, as a reference, in dbhi/docker images from qus are used to build and publish multi-arch images/manifests in an AMD64 only CI service.

It is mostly meant for CI and for development purposes. On the one hand, using this approach allows to build, test and publish multi-arch images/manifests using regular amd64 only CI services (such as GitHub Actions or Travis CI). On the other hand, it allows developing and testing applications for embedded devices (say SBCs or SoCs with FPGA) from amd64 workstations.

buildx

With buildx the same Dockerfile can be used to produce in parallel images which can execute on different hardware architecture. buildx requires either an installation of QEMU or dbhi/qus. The result is a set of comparable Docker images, which run on different hardware and produce identical effects. An introduction is given in Artur Klauser: Building Multi-Architecture Docker Images With Buildx. Basically buildx allows to automate multiple architecture builds and manifest generation in one command.

Clone this wiki locally