How to Build Docker Containers for Multiple Architectures
19 Apr 2020
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.