はじめに
Dockerボリュームのバックアップ方法について試してみました
ググるとよく見つかるのが、以下①の手段なんですが、②でも出来るような気がしたので試してみました
① 別の軽量Linuxコンテナとボリュームマウント、バインドマウントを使ってバックアップ
② ボリュームごとホストへコピー
結果
無事①②両方ともでバックアップもリストアも出来ましたが、Docker ドキュメント日本語化プロジェクトに以下の記載があったので、
ボリューム(volume) は、 「Docker によって管理されている」ホストファイルシステム上の一部に保管します( Linux 上では /var/lib/docker/volumes )。 Docker 以外のプロセスは、このファイルシステム上の一部を変更すべきではありません。 ボリュームは Docker 内のデータを保持するために一番良い方法です。
②で対応する場合は、私が検証したような後述する手段(xcopy等)は避けて、docker cp
等を用いるべきなんだと思います。でもまぁ、ググると①ばかり見つかるので、結局は①に落ち着きそうです。
検証してみる
今回検証するコンテナとボリュームの構成
先に②の検証
まずはコンテナを止めます
$docker stop wordpress01
$docker stop mysql01
続いてボリュームをホストPCの任意のディレクトリへ退避します
なおボリュームは、Docker Desctop for Windowsだと\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes
にあるので、これをコピーするだけです
$ xcopy \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\wp-data .\wp-data /E/H/C/I
$ xcopy \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\db-data .\db-data /E/H/C/I
コンテナとボリュームを削除します
$ docker rm wordpress01
$ docker rm mysql01
$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
wp-data
db-data
ホストPCに退避したデータをボリュームへコピーします
$ xcopy .\db-data \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\db-data /E/H/C/I
$ xcopy .\wp-data \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\wp-data /E/H/C/I
リストアの確認のためにコンテナとボリュームを作ります
$ docker volume create db-data
$ docker volume create wp-data
$ docker run --restart=always --name mysql01 -dit --net=wp_network01 -v db-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=db -e MYSQL_USER=user -e MYSQL_PASSWORD=pass mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password
$ docker run --restart=always --name wordpress01 -dit --net=wp_network01 -v wp-data:/var/www/html -p 8080:80 -e WORDPRESS_DB_HOST=mysql01 -e WORDPRESS_DB_NAME=db -e WORDPRESS_DB_USER=user -e WORDPRESS_DB_PASSWORD=pass wordpress
http://localhost:8080/ へアクセスすると、バックアップした時点の状態でWordPressが表示されました
続いて①の検証
MySQL側だけの図ですが、こんな感じバックアップ用にbusyboxコンテナを作ります(割愛してますが、WordPressも同じイメージです)
こちらも、まずはコンテナを止めます
$docker stop wordpress01
$docker stop mysql01
バックアップです
- 軽量のLinuxコンテナ(今回はbusybox)を使ってバックアップします
このコンテナはすぐに削除するので--rm
オプションをつけています - busyboxコンテナですが、バックアップ元をボリューム指定することに加え、バックアップ先にバインドマウントを指定するところがポイントになるのかと
docker run --rm -v <バックアップ元(ボリューム)> -v <バックアップ先(バインドマウント)> busybox tar <tarコマンドのオプション>
$ docker run --rm -v db-data:/var/lib/mysql -v ${pwd}/bkp:/db-bkp busybox tar czvf /db-bkp/db_backup.tar.gz -C /var/lib/mysql .
$ docker run --rm -v wp-data:/var/www/html -v ${pwd}/bkp:/wp-bkp busybox tar czvf /wp-bkp/wp_backup.tar.gz -C /var/www/html .
コンテナとボリュームを削除します
$ docker rm wordpress01
$ docker rm mysql01
$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
wp-data
db-data
リストアです。バックアップとはtarのオプションが異なるだけ
$ docker run --rm -v db-data:/var/lib/mysql -v ${pwd}/bkp:/db-bkp busybox tar xzvf /db-bkp/db_backup.tar.gz -C /var/lib/mysql
$ docker run --rm -v wp-data:/var/www/html -v ${pwd}/bkp:/wp-bkp busybox tar xzvf /wp-bkp/wp_backup.tar.gz -C /var/www/html
リストアの確認のためにコンテナとボリュームを作ります
$ docker volume create db-data
$ docker volume create wp-data
$ docker run --restart=always --name mysql01 -dit --net=wp_network01 -v db-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=db -e MYSQL_USER=user -e MYSQL_PASSWORD=pass mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password
$ docker run --restart=always --name wordpress01 -dit --net=wp_network01 -v wp-data:/var/www/html -p 8080:80 -e WORDPRESS_DB_HOST=mysql01 -e WORDPRESS_DB_NAME=db -e WORDPRESS_DB_USER=user -e WORDPRESS_DB_PASSWORD=pass wordpress
http://localhost:8080/ へアクセスして、復元できていることを確認して終了です