こんにちは。ニフティ株式会社の島田です。
AppleのContainerizationフレームワークが6月10日に発表されましたが、この記事ではlima-vm + docker-cliで脱Docker Desktopをしてみました。
これは何?
- limaでdockerを使おう
- limaで Apple Virtualization framework + rosetta2 を使って低負荷高速にx86_64イメージを実行しよう
- limaで実行したdocker engineを使ってvscode devcontainerを起動しよう
lima-vmとは
Limaは自動的なファイル共有とポートフォワード機能つきでLinux仮想マシンを起動します(WSL2と同様)。
Limaは、Macユーザへnerdctl (contaiNERD ctl)を含むcontainerdを普及させることを当初の最終目標に据えていました。しかし、Limaではコンテナ化されていないアプリケーションも実行することができます。
Limaは他のコンテナエンジン(Docker, Podman, Kubernetes 等)やmacOS以外のホスト(Linux, NetBSD 等)での動作もサポートしています。
https://github.com/lima-vm/lima/blob/v0.23.2/README.ja.md
- 現在は CNCF Sandbox プロジェクトとして管理されています。OSS(Apache 2.0)
- lima-vmは以下のようなプロジェクトにも採用されています。
- Rancher Desktop
- Colima
- Finch
- Podman Desktop
limaでvmを起動する
1 |
brew instal lima |
1 |
limactl start test |
- vmにアタッチ
1 |
limactl shell test |
- vmを停止
1 |
limactl stop test |
- vmを削除
1 |
limactl rm test |
limaでdocker engineを動かす
- docker desktopをアンインストールする
1 |
/Applications/Docker.app/Contents/MacOS/uninstall |
- docker desktopが作ったファイルを削除する
1 2 3 |
rm -rf ~/Library/Group\ Containers/group.com.docker rm -rf ~/Library/Containers/com.docker.docker rm -rf ~/.docker |
権限が足りないと言われる場合
設定> プライバシーとセキュリティ> フルディスクアクセス> ターミナルをオン
必要に応じてsudoを付けて実行

- docker-cliをインストールする
1 |
brew install docker |
- limaでvmを作成、docker engine(rootful)を起動する
- テンプレートから起動する場合、vmの名前がテンプレートのファイル名になる
1 |
limactl create template://docker-rootful --vm-type=vz --rosetta --cpus=8 --memory=16 --mount-writable=書き込み可能にしたいパス(vscodeプロジェクトを配置してるパスとか) |
https://github.com/lima-vm/lima/blob/master/templates/docker-rootful.yaml
rootlessでいい場合は以下のテンプレートを使う
1 |
limactl create template://docker --vm-type=vz --rosetta --cpus=8 --memory=16 --mount-writable=書き込み可能にしたいパス(vscodeプロジェクトを配置してるパスとか) |
https://github.com/lima-vm/lima/blob/master/templates/docker.yaml
- 起動後に出力されるdocker contextを登録して切り替える
1 2 |
docker context create lima-rootful --docker "host=unix:///Users/`whoami`/.lima/docker-rootful/sock/docker.sock" docker context use lima-docker-rootful |
rootlessの場合
1 2 |
docker context create lima-rootful --docker "host=unix:///Users/`whoami`/.lima/docker-rootful/sock/docker.sock" docker context use lima-docker-rootful |
- docker engineとdocker cliが通信できることを確認する
1 |
docker version |
出力例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
brew % docker version Client: Docker Engine - Community Version: 27.3.1 API version: 1.47 Go version: go1.23.1 Git commit: ce1223035a Built: Fri Sep 20 11:01:47 2024 OS/Arch: darwin/arm64 Context: lima-rootful Server: Docker Engine - Community Engine: Version: 27.3.1 API version: 1.47 (minimum version 1.24) Go version: go1.22.7 Git commit: 41ca978 Built: Fri Sep 20 11:41:54 2024 OS/Arch: linux/arm64 Experimental: false containerd: Version: 1.7.22 GitCommit: 7f7fdf5fed64eb6a7caf99b3e12efcf9d60e311c runc: Version: 1.1.14 GitCommit: v1.1.14-0-g2c9f560 docker-init: Version: 0.19.0 GitCommit: de40ad0 |
lima+dockerでdevcontainerを起動する
- compose、buildx拡張をダウンロードしてdocker-cliから使えるようにする
1 2 3 4 5 6 7 8 9 |
brew install docker-compose brew install docker-buildx mkdir -p ~/.docker/cli-plugins ln -s /opt/homebrew/bin/docker-compose ~/.docker/cli-plugins/. ln -s /opt/homebrew/bin/docker-buildx ~/.docker/cli-plugins/. docker compose version docker buildx version |
- vscode(devcontainer)はdocker contextを使ってくれない
選択肢1: /var/run/docker.sock
にシンボリックリンクを作成する
vmが停止したタイミングでdocker.sockが消えるので起動するたびに張り直しが必要
1 |
sudo ln -s ~/.lima/docker-rootful/sock/docker.sock /var/run/docker.sock |
選択肢2: vscodeが見るdocker endpointを変更する(基本こっちがおすすめ)
vscodeを開き、command + ,
で設定を開く
dev.containers.dockerSocketPath
で検索
自分のdocker endpoint(~/.lima/docker-rootful/sock/docker.sock
)に変更する

その他覚えておくと便利なこと
- ドキュメントが優秀なので基本そっちを見たほうが分かります
- vm停止状態で
limactl edit
するとvmの定義ファイルを開いて編集できる - vmの設定は
~/.lima
配下にある./lima/vm-name/lima.yaml
に今の設定があるので削除前に保存しておくことができる
- シャットダウン時vscodeを起動したままだと次回起動後docker hostを認識してくれない
- vscodeを再起動する
- 自動採番されるdocker networkのipレンジを変更する
- 以下を参考に
daemon.json
を配置するように書き換える - rootlessはmodeと配置先を変更する必要がある
- 以下を参考に
daemon.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# A template to use Docker (rootful) instead of containerd & nerdctl # $ limactl start ./docker-rootful.yaml # $ limactl shell docker-roootful docker run -it -v $HOME:$HOME --rm alpine # To run `docker` on the host (assumes docker-cli is installed): # $ export DOCKER_HOST=$(limactl list docker-rootful --format 'unix://{{.Dir}}/sock/docker.sock') # $ docker ... # This template requires Lima v0.20.0 or later vmType: "vz" rosetta: # Enable Rosetta for Linux. # Hint: try `softwareupdate --install-rosetta` if Lima gets stuck at `Installing rosetta...` enabled: true # Register rosetta to /proc/sys/fs/binfmt_misc binfmt: true cpus: 8 memory: 16GiB images: # Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months. - location: "https://cloud-images.ubuntu.com/releases/24.04/release-20241004/ubuntu-24.04-server-cloudimg-amd64.img" arch: "x86_64" digest: "sha256:fad101d50b06b26590cf30542349f9e9d3041ad7929e3bc3531c81ec27f2c788" - location: "https://cloud-images.ubuntu.com/releases/24.04/release-20241004/ubuntu-24.04-server-cloudimg-arm64.img" arch: "aarch64" digest: "sha256:e380b683b0c497d2a87af8a5dbe94c42eb54548fa976167f307ed8cf3944ec57" # Fallback to the latest release image. # Hint: run `limactl prune` to invalidate the cache - location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img" arch: "x86_64" - location: "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-arm64.img" arch: "aarch64" mounts: - location: "~" - location: "/tmp/lima" writable: true # containerd is managed by Docker, not by Lima, so the values are set to false here. containerd: system: false user: false provision: - mode: system script: | #!/bin/sh mkdir -p /etc/docker/ cat <<EOF > /etc/docker/daemon.json { "default-address-pools": [ {"base":"192.168.0.0/16", "size":24} ] } EOF - mode: system # This script defines the host.docker.internal hostname when hostResolver is disabled. # It is also needed for lima 0.8.2 and earlier, which does not support hostResolver.hosts. # Names defined in /etc/hosts inside the VM are not resolved inside containers when # using the hostResolver; use hostResolver.hosts instead (requires lima 0.8.3 or later). script: | #!/bin/sh sed -i 's/host.lima.internal.*/host.lima.internal host.docker.internal/' /etc/hosts - mode: system script: | #!/bin/bash set -eux -o pipefail command -v docker >/dev/null 2>&1 && exit 0 if [ ! -e /etc/systemd/system/docker.socket.d/override.conf ]; then mkdir -p /etc/systemd/system/docker.socket.d # Alternatively we could just add the user to the "docker" group, but that requires restarting the user session cat <<-EOF >/etc/systemd/system/docker.socket.d/override.conf [Socket] SocketUser={{.User}} EOF fi export DEBIAN_FRONTEND=noninteractive curl -fsSL https://get.docker.com | sh probes: - script: | #!/bin/bash set -eux -o pipefail if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then echo >&2 "docker is not installed yet" exit 1 fi if ! timeout 30s bash -c "until pgrep dockerd; do sleep 3; done"; then echo >&2 "dockerd is not running" exit 1 fi hint: See "/var/log/cloud-init-output.log" in the guest hostResolver: # hostResolver.hosts requires lima 0.8.3 or later. Names defined here will also # resolve inside containers, and not just inside the VM itself. hosts: host.docker.internal: host.lima.internal portForwards: - guestSocket: "/var/run/docker.sock" hostSocket: "{{.Dir}}/sock/docker.sock" message: | To run `docker` on the host (assumes docker-cli is installed), run the following commands: ------ docker context create lima-{{.Name}} --docker "host=unix://{{.Dir}}/sock/docker.sock" docker context use lima-{{.Name}} docker run hello-world ------ |