Docker on LimaでdockerのデータをVM外に保存する
LimaでDockerを動かしている。
のだが、Dockerのデータ(コンテナイメージやボリュームなど)がLimaのVM内に保存されていると、VMを消して作り直したときにDockerのデータが失われてしまい、とても悲しい。
そこで、DockerのデータをVM外に保存して、VMを消して作り直してもDockerのデータが消えないようにしてみた。
方策は、Dockerのデータ保存先をLimaのdiskにする、というものである。
以下に手順の詳細を示す。
動作検証環境
- Lima 0.14.2
- 使用したVM:
limactl start --name=docker template://docker
手順
1: Limaのdiskを作成する
limactl disk
コマンドを使って、Dockerデータを保存するためのdiskを作成する。
$ limactl disk create dockerdata --size 64G
ディスク名(上記例ではdockerdata)、サイズ(上記例では64G)は好みの値でOK。
作成されたdiskは~/.lima/_disksに配置される。
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 $LIMA_CIDATA_USER:$LIMA_CIDATA_USER /mnt/lima-dockerdata
3: Dockerのデータ保存先を変更する
lima.yamlに以下の記述を追加する。追加位置は、手順2で追加したprovisionのすぐ後でよい。
provision:
- mode: system # ここは手順2で追加した内容
script: |
#!/bin/bash
set -eux -o pipefail
chown $LIMA_CIDATA_USER:$LIMA_CIDATA_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
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 cp -rp ~/.local/share/docker/* /mnt/lima-dockerdata
コピーが終わったら、dockerデーモンを起動する。
lima-docker$ systemctl --user start docker
既存のDockerデータが移行されているか確認する。
$ docker ps -a
$ docker images
$ docker volume ls
おまけ
VMを停止せずにPCシャットダウンすると、次回VMを起動する際に以下のようなエラーが出る。
[hostagent] could not attach disk "dockerdata", in use by instance "docker"
この場合、以下のコマンドを実行して、diskのロックを解除する。
limactl disk unlock dockerdata
Discussion