💽

Docker on LimaでdockerのデータをVM外に保存する

に公開

LimaでDockerを動かしている。
のだが、Dockerのデータ(コンテナイメージやボリュームなど)がLimaのVM内に保存されていると、VMをfactory-resetしたときにDockerのデータが失われてしまい、とても悲しい。
そこで、DockerのデータをVM外に保存して、VMを消して作り直してもDockerのデータが消えないようにしてみた。

方策は、Dockerのデータ保存先をLimaのdiskにする、というものである。
以下に手順の詳細を示す。

動作検証環境

  • Lima 1.0.7
  • 使用したVM: limactl start --name=docker template://docker
  • macOS 15.3.2

手順

1: Limaのdiskを作成する

limactl diskコマンドを使って、Dockerデータを保存するためのdiskを作成する。

$ limactl disk create dockerdata --size 64G --format raw

ディスク名(上記例ではdockerdata)、サイズ(上記例では64G)は好みの値でOK。
フォーマットはVZならraw、QEMUならqcow2にすればよい。が、違うフォーマットにしても、VMインスタンス起動時に適切なフォーマットに変換される。

作成されたdiskは~/.lima/_disksに配置される。

※Lima v1.0.7時点では、limactl disk createコマンドを実行する際にディスクのフォーマットに関わらずQEMUが必要。QEMUをインストールしていない場合は、brew install qemuなどを実行してインストールしておく。
v1.1.0-alpha以降なら、rawフォーマットの場合はQEMUは不要。(このコミットがマージされている。)

2: LimaのVMにdiskをマウントする

lima.yamlに以下の記述を追加する。

additionalDisks:
- dockerdata

これで、VM内の/mnt/lima-dockerdataにdiskがマウントされる。
ただし、これだけでは/mnt/lima-dockerdataのオーナーがrootとなり、rootlessなdockerのデータを保存できない。
これを解決するために、lima.yamlのprovisionの一番先頭に以下を追加する。

provision:
- mode: system
  script: |
    #!/bin/bash
    set -eux -o pipefail
    chown {{.User}}:{{.User}} /mnt/lima-dockerdata

3: Dockerのデータ保存先を変更する

lima.yamlに以下の記述を追加する。追加位置は、手順2で追加したprovisionのすぐ後でよい。

provision:
- mode: system # ここは手順2で追加した内容
  script: |
    #!/bin/bash
    set -eux -o pipefail
    chown {{.User}}:{{.User}} /mnt/lima-dockerdata
- mode: user # ここから追加
  script: |
    #!/bin/bash
    set -eux -o pipefail
    DOCKER_DAEMON_JSON={{.Home}}/.config/docker/daemon.json
    if [ ! -f "$DOCKER_DAEMON_JSON" ]; then
      mkdir -p $(dirname $DOCKER_DAEMON_JSON)
      echo '{"data-root":"/mnt/lima-dockerdata"}' >$DOCKER_DAEMON_JSON
    fi

4: 設定を確認する

VMを起動して、docker infoの結果を確認する。

$ limactl start docker
$ docker info

得られた出力に以下のような内容があれば成功。

Docker Root Dir: /mnt/lima-dockerdata

うまくいかない場合

VM内に$HOME/.config/docker/daemon.jsonが存在するか、その内容が間違っていないかを確認する。
daemon.jsonの内容が間違っていないのに「Docker Root Dir」が変わっていない場合、VM内でdockerデーモンを再起動してみる。

lima-docker$ systemctl --user restart docker

※VM内で実行するコマンドは「lima-docker$ ...」の形で記載している。

5: (必要ならば)既存のDockerデータをdiskに移行する

この手順は、VM内にすでにDockerデータが保存されていて、それをVM外に保存しなおしたい場合にのみ行う。新規VMを作る場合や、Dockerデータの移行が不要な場合は、この手順は実施不要。

VM内でdockerデーモンを停止する。

lima-docker$ systemctl --user stop docker

rootlessなdockerのデフォルトのデータ保存先は$HOME/.local/share/docker。
VM内のそのディレクトリの内容を/mnt/lima-dockerdataにコピーする。

lima-docker$ sudo rsync -axPS ~/.local/share/docker/ /mnt/lima-dockerdata

コピーが終わったら、dockerデーモンを起動する。

lima-docker$ systemctl --user start docker

既存のDockerデータが移行されているか確認する。

$ docker ps -a
$ docker images
$ docker volume ls

Discussion