Fragile Little World


How to Build Docker Containers for Multiple Architectures

19 Apr 2020

Docker containerization logo

Docker and similar containerization tools allow for application isolation with minimal overhead by virtualizing the upper layers of the operating system kernel

Docker is a tool for isolating applications and managing dependencies with minimal overhead compared to traditional virtualization techniques. This guide shows you how to build images for the power saving ARM architecture on a normal x64 workstation.

Recently, I have been working with Docker at work, and have been thinking of using it to make managing dependencies for personal projects simpler. One of my first applications was to create containers to use on my Raspberry Pi, which understandably creates some issues with building across architectures. Since it would be a lot of work to remote into a low power ARM board and build an image on it, I decided to look into ways to build the images on my desktop computer. Docker is capable of this, but I couldn’t find a resource doing quite what I needed. In the end, I combined a few resources to bring you this tutorial.

First off, you’ll need a few supporting packages and Docker 19.03. My commands will be for Ubuntu based Linux distributions, but the general gist should hold for other *nix operating systems, as well as Windows through Windows Subsystem for Linux or within a Docker container.

$ sudo apt install binfmt-support \
                   qemu-user-static \
                   docker.io

$ sudo usermod -aG docker $USER

This will install QEMU, which allows emulation of an ARM processor for cross compiling and even running Docker images created for ARM, while binfmt allows support for multiple different binaries. Make sure your Linux kernel is at least 5.x at this point, and that binfmt-support is at least version 2.1.43 to support what we need. Lastly, the current user is modified to allow you to call docker without needing sudo. Reboot after this, as these packages enable features in the kernel.

Next we need to install buildx, a modified version of the Docker build command that supports what we are trying to do. You can download a binary from Github, or download and compile the source if you prefer. Once you have it, move it to ~/.docker/cli-plugins/, rename it to docker-buildx, and make sure it is executable.

Now you should be all ready to set up your builds for multiple architectures! Just a few more steps to do that:

# Create a new builder, you can have several
$ docker buildx create --name newbuilder

# Set it as the default
$ docker buildx use newbuilder

# Complete the setup of the builder
$ docker buildx inspect --bootstrap

After the last command, you should see a list of platforms including your own as well as several others like arm64. If you are on an Ubuntu 18.04 based distro like me or it otherwise did not quite work, there is a way around it. You can run a command that properly registers the cross-compiling capabilities you have with Docker, like so:

docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

Double check that that worked by calling inspect again, and if so, you’re off to the races! To check what platforms a base image supports, you can run

$ docker buildx imagetools inspect <your favorite image>

To build for multiple platforms, run docker buildx build with the --platform flag accompanied by a comma separated list of all the platforms you would like to build for.

References and Footnotes

Building Multi-Architecture Docker Images on ARM 64-bit AWS Graviton2 Processors

Running and building ARM Docker containers in x86

Getting started with Docker for Arm on Linux

Running and Building ARM Docker Containers on x86


Have questions or looking to discuss this article? Email contact@fragilelittle.world.