Running containers on your Mac can be a challenge. After all, containers are based on Linux-specific technologies like cgroups and namespaces.
Luckily, macOS has a built-in hypervisor, allowing virtual machines (VMs) on the Mac. The hypervisor is a low-level kernel feature, not a user-facing one.
hyperkit, an open source project that will run VMs using the macOS hypervisor. The
hyperkit tool is designed to be a "minimalist" VM runner. Unlike, say, VirtualBox, it does not come with fancy UI features to manage VMs.
You can grab
hyperkit, a minimalist Linux distribution running a container manager, and plumb all the pieces together. This would be a lot of moving parts, and sounds like a lot of work. Especially if you want to make the network connections a bit more seamless by using
vpnkit, an open source project to create a VM's network that feels more like part of the host's network.
$ brew install lima
After installation, which might take a while, it is time to begin having some fun. In order to let
lima know you are ready for some fun, you need to start it. Here's the command:
$ limactl start
If this is your first time, you will be asked if you like the defaults or whether you want to change any of them. The defaults are pretty safe, but I like to live on the wild side. This is why I jump into an editor and make the following modifications from:
- location: "~" # CAUTION: `writable` SHOULD be false for the home directory. # Setting `writable` to true is possible but untested and dangerous. writable: false
- location: "~" # I *also* like to live dangerously -- Austin Powers writable: true
As it says in the comment, this can be dangerous. Many existing workflows, sadly, depend on this mounting to be read-write.
containerd to manage containers. The
containerd manager is also a pretty frill-less one. While it is not uncommon to use a wrapper daemon, like
dockerd, to add those nice-to-have ergonomics, there is another way.
The nerdctl tool
nerdctl tool is a drop-in replacement for the Docker client which puts those features in the client, not the server. The
lima tool allows running
nerdctl without installing it locally, directly from inside the VM.
Putting it all together, it is time to run a container! This container will run an HTTP server. You can create the files on your Mac:
$ ls index.html $ cat index.html hello
Now, mount and forward the ports:
$ lima nerdctl run --rm -it -p 8000:8000 -v $(pwd):/html --entrypoint bash python root@9486145449ab:/#
Inside the container, run a simple web server:
$ lima nerdctl run --rm -it -p 8000:8000 -v $(pwd):/html --entrypoint bash python root@9486145449ab:/# cd /html/ root@9486145449ab:/html# python -m http.server 8000 Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
From a different terminal, you can check that everything looks good:
$ curl localhost:8000 hello
Back on the container, there is a log message documenting the HTTP client's connection:
10.4.0.1 - - [09/Sep/2021 14:59:08] "GET / HTTP/1.1" 200 -
One file is not enough, so times to make some things better. CTRL-C the server, and add another file:
^C Keyboard interrupt received, exiting. root@9486145449ab:/html# echo goodbye > foo.html root@9486145449ab:/html# python -m http.server 8000 Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Check that you can see the new file:
$ curl localhost:8000/foo.html goodbye
To recap, installing
lima takes a while, but after you are done, you can do the following:
- Run containers.
- Mount arbitrary sub-directories of your home directory into containers.
- Edit files in those directories.
- Run network servers that appear to Mac programs like they are running on localhost.