Good with a keyboard and fluent in gibberish

Gamebear 2.5: Cross-running Containers

This is a follow-up to my previous post about building with containers. It turns out, there’s a way to run ARM containers on AMD64 systems.

It involves calling QEMU via binfmt_misc, basically allowing for ARM binaries to run directly on your system.

This allows us to compile software for Raspberry Pi without needing to do it on an actual Raspberry Pi or setting up cross-compiling environments.

First of all: Why this works requires properly understanding what containers actually are. I suggest Wizard Zines’ How Containers Work! if you don’t already know what cgroups and namespaces are.

Ok, so now you know that containers are a collection of namespaces and such. The way we use an ARM container isn’t like we spin up an ARM virtual machine and run the container inside that. We just start a regular container from the ARM image. The secret is that because the host has QEMU+binfmt set up, it is able to directly run the ARM programs inside the container transparently. You don’t even need to do anything special for your container tools.

How do we make this magical setup?

On Debian Bullseye (11, Testing as of this writing) and Ubuntu 20.04, you just have to install the qemu-user-static package. On older systems, there’s extra gymnastics you have to do to enable binfmt_misc to use qemu-user-static.

Note that you have to use the static versions of QEMU, because it has to run inside a fairly unhelpful container–dynamic linking will fail if there aren’t any AMD64 libs to be seen, such as in an ARM container.

After this is done, the build script in the previous post can now be:

#!/bin/sh
set -e

buildahscript-py buildscript.py

Or, you know, just invoke it directly.