Blog

How to build Intel Docker containers on Mac M1

22 Jun, 2022
Xebia Background Header Wave

Lima is a tool that is very often described as the containerd for Mac. With it you can run a linux operating system alongside your Mac. It features automatic port forwarding, seemless file sharing, and supports various linux distributions such as AlmaLinux, Alphine, Arch Linux, Debian, Fedora, SUSE, Oracle Linux, Rocky and Ubuntu. By default it comes with containerd and nerdctl, but you can use Lima for non-container tasks as well.

Mac computers with Apple sillicon

Late 2020 Mac released their first systems with Apple Silicon, a custom designed Arm-based chip for Mac. The most recent editions of the Macbook pro uses the M1 Apple Silicon processor, whereas it used to be an Intel processor. Their new custom chipset is unable to process Intel instructions without the aid of additional software. Applications that have been built for Intel can still be used on a Mac with the use of emulation software that Apple has made available: "Rosetta 2".

The Rosetta 2 software, however, has some limitations as to what it can process. In particular it's often incompatible with virtual machine applications, which brings us to the next topic: Docker.

Challenges with Docker using the new M1 processor

A significant portion of developers use Docker for their local development work. By default Docker does support emulating amd64 by specifying the --platform linux/amd64 flag for building and running containers. Most images and packages are available for amd64, but not every package has transitioned. I recently had a use case where I absolutely needed an Intel architecture for a container. The options I had were either building the image on my old Macbook, or spin up a virtual machine with the correct architecture.

Setting up Lima to build docker images

And in comes Lima. My goal was to set up an environment in which I could build Docker containers as I was used to, without having to transfer files to another system or resort to my old Macbook. Lima is the perfect tool to do so.

You can install lima on MacOS using brew: brew install lima. Once it's installed: limactl start and choose:

Open an editor to review or modify the current configuration

On the line where it says arch: null replace null with x86_64. By default it will use the architecture of your operating system (in the case of an M1 it's aarch64). After you save the configuration file, type the following commands:

limactl shell default
sudo systemctl start containerd
sudo nerdctl run --privileged --rm tonistiigi/binfmt --install all
exit

This is required for the guest OS to be able to execute non-native binaries. And that's it for installation! Lima comes with containerd and nerdctl for building docker images.

Creating an alias to make building Docker images with Lima easy

The method of building Docker containers is normally as follows: lima nerdctl build ., where lima nerdctl is a drop-in replacement for the docker command. To keep my current way of working, I've added an alias:

alias docker='lima nerdctl'

Type:

echo alias docker=\'lima nerdctl\' >> ~/.zprofile to make this alias persistent. Now you can use the docker command as usual, but build and run images using an emulated Intel processor. You can change the name of the alias (e.g. dockerr) if you want to keep being able to use your native architecture to build images.

When you run a docker image through lima, port forwarding is automatically arranged, so any port your container listens on is exposed on localhost. In addition, you can create several lima instances and use them concurrently. The limactl start command has an optional argument: limactl start foobar will create a lima instance called foobar, and with LIMA_INSTANCE=foobar lima [command] you can execute commands on that specific instance.

Drawbacks

By default your Mac home directory is read only. This is intentional. Write support on Mac home directories is experimental. You can yolo it by editing the ~/.lima/default/lima.yaml file and set writable to true and restart lima (limactl stop && limactl start). Having said that, the lima home directory is writable, so if you simply place your code there it negates the need to make the Mac home directory writable.

Another drawback is the speed. Especially if you're compiling stuff in your container you really notice the difference between a native architecture and an emulated one. Unfortunately that is not to change any time soon.

Dennis Vink
Crafting digital leaders through innovative AI & cloud solutions. Empowering businesses with cutting-edge strategies for growth and transformation.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts