The weirdness that is AMD64 on Apple M1 Silicon

OK, spent an hour with Alex working on this problem. He has some docker images which will not build on Apple AARCH64 (aka Arm64) architecture because they are so old. But Docker apparently allows you to run and build containers that are multiarchitecture. The problem is that the current Docker for Mac v4.3 has a QEMU crash with qemu uncaught target signal 6 when running.

So what is going on? Well first of all on an Apple M1, what Docker Desktop for the Mac does is that it runs using a hypervisor inside of Apple. And if it detects it needs to run an Intel container (technically this is called an Linux/amd64 container since AMD did the first 64-bit extension to Intel), then it will run QEMU which is an emulator inside of an Apple hypervisor session.

And in fact, if you set DOCKER_DEFAULT_PLATFORM=linux/amd64 as an environment variable and it will always pull images that are for Intel onto your M1 machine which is pretty cool if you are doing Intel image development for say a cloud application.

Or the long form is using a new flag:

docker run -p 8888:8888 --platform=linux/amd64 jupyter/minimal-notebook

This will find the AMD64 version of the minimal Jupyter notebook and then get the image, start an M1 virtual machine and then start a container that runs under QEMU which translates Intel instructions into ARM instructions

Using Buildx to build containers

You can infact do builds using something called buildx which knows how to do multiple builds for multiple architectures which is pretty cool so:

docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t richt/demo-image .

And what this does is create a container called demo-image and it will build for Intel/AMD 64-bit, ARM64 which is for Apple Silicon and Arm v7

What is all this about Signal 6 in QEMU but it works with Docker v4.0

Well, the long and short of it is that no one knows what is going on. Turns out that Docker Desktop for Mac ships with its own version of QEMU kept in /Applications/Docker.app/Contents/MacOS/qemu-system-aarch64 and they maintain their own version of QEMU which appears to be way behind the master. And in fact you can run it as a command-line thing and for Docker 4.3 it returns that it is the v5.2.0-11 Docker version of the emulator which is way behind like 20,000 commits behind (you can see this in their open source project), the current version 6.2, so it is kind of temping just to copy the binary over and see what happens :-):

bash> /Applications/Docker.app/Contents/MacOS/qemu-system-aarch64 --version
QEMU emulator version 5.2.0 (v5.2.0-11-ge7395802aa)
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers

Note that with the M1, Docker is switching to the new hypervisor system from Apple, but even then there are performance differences if you click on to enable new hypervisor. It appears to be much slower, so don’t do it 🙂

There are quite a few outstanding questions about this as ordinary containers like docker run --platform=linux/amd64 alpine sh run fine, but not other containers like Jupyter Notebooks.

The main working solution right now courtesy of @anciltech is that his Jupyter project working fine up until Docker version 4.0.0 and broke with v4.1.x, so just go back to that.

Some other solutions try a VM

If this continue to be a problem, then you might have to buy a complete virtual machine environment, but it is probably better to just hope that the Docker folks fix it. But you could try Parallels which is expensive or you could try UTM which is $10 and uses QEMU (there it is again) underneath to emulate x86/arm64 containers.

I’m Rich & Co.

Welcome to Tongfamily, our cozy corner of the internet dedicated to all things technology and interesting. Here, we invite you to join us on a journey of tips, tricks, and traps. Let’s get geeky!

Let’s connect