Docker on Lima is one of the alternative solutions to Docker Desktop for Mac.
Many people have already described the steps to set up for that.
In addition to such a standard setup, this guide describes how to set up a Docker environment which can run multi-arch images.
For example, you will be able to run linux/amd64
images on your M1 Mac.
- Assume that Homebrew is already installed:
$ brew -v Homebrew 3.4.9
- Install Lima:
$ brew install lima ... $ lima -v limactl version 0.10.0
To configure Lima VM itself, default.yaml
may be helpful.
Here we will explain minimal changes only.
- Download docker.yaml.
$ curl -O https://raw.githubusercontent.com/lima-vm/lima/3190530a8e0f10b4000efdebcdfdc2a799da65fa/examples/docker.yaml
- Add the following lines into
docker.yaml
. This script runs tonistiigi/binfmt to enable QEMU emulation for Docker Engine:My# NOTE: you may remove the lines below, if you prefer to use rootful docker, not rootless systemctl disable --now docker apt-get install -y uidmap dbus-user-session +- mode: system + script: | + #!/bin/bash + # enable docker cpu emulation + # cf. https://github.com/lima-vm/lima/blob/master/docs/multi-arch.md + docker run --privileged --rm tonistiigi/binfmt --install all - mode: user script: | #!/bin/bash
docker.yaml
is here. - Launch Lima VM:
$ limactl start --tty=false ./docker.yaml
- Verify your setup:
Congratulations! Now you have already been able to run both images for Arm (# Show the list of VMs host$ limactl list docker NAME STATUS SSH ARCH CPUS MEMORY DISK DIR docker Running 127.0.0.1:50084 aarch64 4 4GiB 100GiB /Users/YourName/.lima/docker # Enter to the shell of VM (guest) host$ limactl shell docker # Verify the architecture of VM machine guest$ uname -a Linux lima-docker 5.15.0-25-generic #25-Ubuntu SMP Wed Mar 30 15:57:31 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux # Trying to run the `hello-world` image on Docker guest$ docker pull hello-world guest$ docker image inspect hello-world --format '{{.Architecture}}' arm64 guest$ docker run --rm hello-world ... 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (arm64v8) ... # The above example runs the image for native architecture. # Next, we will run the image for the other architecture (e.g. for Intel CPUs). guest$ docker image rm hello-world guest$ docker pull --platform linux/amd64 hello-world guest$ docker image inspect hello-world --format '{{.Architecture}}' amd64 guest$ docker run --rm --platform linux/amd64 hello-world ... 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) ...
linux/arm64/v8
) and for Intel (linux/amd64
).
In the previous step, we have been able to use Docker in the Lima VM. Next, we will configure the host to have direct access to the Docker Engine.
- Install Docker CLI in the host:
host$ brew install docker ... host$ docker -v Docker version 20.10.14, build a224086349
- Configure:
- Option.a) Create new context:
Then enable the context named
host$ docker context create lima \ --docker "host=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')"
lima
:host$ docker context use lima
- Option.b) Set
DOCKER_HOST
environment variable; add the following lines into your~/.zshrc
:Then applyexport DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
~/.zshrc
changes:host$ . ~/.zshrc
- Option.a) Create new context:
- Verify; If you have run the
hello-world
image in the previous section, it should be listed here:host$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a5 3 months ago 13.3kB
We have already installed Buildx in the Lima VM. But it is not available directly from the host.
host$ limactl shell docker docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
rootless * docker
rootless rootless running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
...
host$ docker buildx ls
docker buildx ls
docker: 'buildx' is not a docker command.
See 'docker --help'
You will need to install Buildx on the host manually.
- Install (cf. https://github.com/docker/buildx#manual-download):
host$ mkdir -p ~/.docker/cli-plugins host$ curl -fsSL -o ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.8.2/buildx-v0.8.2.darwin-arm64 host$ chmod +x ~/.docker/cli-plugins/docker-buildx
- Verify:
host$ docker buildx ls NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS lima * docker lima lima running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6 ...
- Install (cf. https://github.com/docker/compose#linux)
host$ curl -fsSL -o ~/.docker/cli-plugins/docker-compose https://github.com/docker/compose/releases/download/v2.5.1/docker-compose-darwin-aarch64 host$ chmod +x ~/.docker/cli-plugins/docker-compose
- Verify:
host$ docker compose version Docker Compose version v2.5.1
-
By default, the Lima VM will not start when you boot your Mac. If you want to start the Docker VM automatically, you can use LaunchAgents.
- Create
~/Library/LaunchAgents/lima-docker.plist
:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>launch-lima-docker</string> <key>ProgramArguments</key> <array> <string>/bin/zsh</string> <string>-lic</string> <string>( limactl stop -f docker; sleep 5; limactl start docker ) > ~/Library/LaunchAgents/lima-docker.plist.log 2>&1</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <false/> <key>AbandonProcessGroup</key> <true/> </dict> </plist>
- Load it:
Then, reboot your mac. The VM$ launchctl load ~/Library/LaunchAgents/lima-docker.plist
docker
will start automatically after you login.
Or, also you can also use crontab.
$ crontab -e # Set PATH # This is an example. Make sure it is appropriate for your environment. PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin # Automatically starts the `docker` VM on Lima. @reboot ( limactl stop -f docker; sleep 5; limactl start docker; ) > /dev/null 2>&1
- Create
-
If you want to show the list of supported architectures, then run:
host$ limactl shell docker sudo docker run --rm --privileged tonistiigi/binfmt { "supported": [ "linux/arm64", "linux/amd64", "linux/riscv64", "linux/ppc64le", "linux/s390x", "linux/386", "linux/mips64le", "linux/mips64", "linux/arm/v7", "linux/arm/v6" ], "emulators": [ "qemu-arm", "qemu-i386", "qemu-mips64", "qemu-mips64el", "qemu-ppc64le", "qemu-riscv64", "qemu-s390x", "qemu-x86_64" ] }
-
Some application will ignore docker contexts. In this case, rootless docker will cause problems. The simplest workaround is to make
/var/run/docker.sock
as a symlink to the socket of rootless docker. Add the following shell script todocker.yaml
:dockerd-rootless-setuptool.sh install docker context use rootless +- mode: user + script: | + #!/bin/bash + set -eux -o pipefail + DOCKER_SOCK_DEFAULT=$(docker context inspect default --format='{{.Endpoints.docker.Host}}' | cut -d '/' -f 3-) + DOCKER_SOCK_ROOTLESS=$(docker context inspect rootless --format='{{.Endpoints.docker.Host}}' | cut -d '/' -f 3-) + sudo rm -f "$DOCKER_SOCK_DEFAULT" + sudo ln -s "$DOCKER_SOCK_ROOTLESS" "$DOCKER_SOCK_DEFAULT" probes: - script: | #!/bin/bash
-
Can Docker on Lima be a complete replacement for Docker Desktop for Mac?
- A quick survey has shown that many of the features that I wanted worked. However, there are still some unstable parts. I am not sure if I can recommend it for production use.
- File sharing (Bind mount):
- Since Lima v0.10.0, new mount option
mountType: 9p
has been added. I have tested it and it seems to be better thanreverse-sshfs
. However, this feature is still experimental. See lima-vm/lima#726 and others for more details. - By setting the
writable
property totrue
, we can read and write the host's file system using bind mount. - A large amount of access to bind-mounted directories will occasionally cause data corruption. For example, this happened when many intermediate files were output in such a directory during program compilation. You should minimize such access, if possible.
- I guess this issue is related to the performance issue of bind mount in docker on mac.
- There is a workaround that changes the consistency option. For example, in
devcontainer.json
:The important part is// devcontainer.json { ... + "workspaceMount": "type=bind,source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},consistency=delegated", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", }
consistency=delegated
. cf. https://docker-docs.netlify.app/docker-for-mac/osxfs-caching/ - However, this workaround doesn't seem to work perfectly well.
- There is a workaround that changes the consistency option. For example, in
- Since Lima v0.10.0, new mount option
- Network access:
- Simple test: Run
$ docker run --rm -p 3000:80 nginx
, then access http://localhost:3000 in your browser (e.g. Safari).
- Simple test: Run
- The following tools seems to work with this setup: