💽

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

2023/04/06に公開

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