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
To keep my current way of working, I've added an alias:
alias docker='lima nerdctl'
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
limactl start foobar will create a lima instance called foobar,
LIMA_INSTANCE=foobar lima [command] you can execute commands on that specific instance.
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
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.