Skip to content

Multiarch setups with QEMU

mviereck edited this page Sep 7, 2020 · 15 revisions

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.

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 multiarch GUI development with the help of x11docker. List of architectures supported by Docker.

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. In fact, QEMU is included in Docker Desktop (Windows and Mac OS) since v1.13.0 (2017-01-19). 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 (GitHub Actions).

A shortcut to allow multiple archtitectures 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. binfmt is a kernel feature.

In fact, docker run --rm --privileged aptman/qus -s -- -p is not limited to using foreign containers. 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.

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. This might be the motivation for the partnership between Docker and ARM, and why QEMU is included in Docker Desktop by default.

For example, binaries built and tested in arm32v7/ubuntu containers can be deployed to PYNQ boards (https://github.com/Xilinx/PYNQ/releases). Such embedded devices are typically slower than workstations, specially for cpu-bound tasks. Hence, even if QEMU introduces a x3-10 execution penalty, development can be faster. Furthermore, using a container is "cleaner" than installing all cross-compilation dependencies on the host. Last, but not least, some of those boards cost >2000€. Hence, the number of devices in the lab (or at home) might be limited.

Summarizing, dbhi/qus is mostly targeted at users that would use QEMU in any case. Nonetheless, other use cases are possible, e.g. running Steam on a RPi.

Clone this wiki locally