はじめに
今まで別のコンテナでMySQLのデータを引き継ぐには、恥ずかしながらボリュームというのを知らず、毎回ダンプしていました。ダンプとリストアって割と手間なんですよね。なので、今回は新たに知ったボリュームを使った紹介したいと思います。
ボリュームとは
ボリュームは、コンテナのデータを永続化するための仕組みです。通常、コンテナ内部のデータはコンテナ削除時に失われますが、ボリュームを利用すると
- コンテナ削除後もデータが保持される
- 複数のコンテナ間でデータを共有できる
というようなメリットがあります。
ボリュームを作成し、MySQLコンテナにマウントする
ボリュームの作成
db-volumeというボリュームを作成します。
% docker volume create --name db-volume
db-volume
MySQLのデータを引き継ぐには、MySQLサーバーがデータを保存するディレクトリにボリュームをマウントする必要があります。デフォルトで、保存先は/var/lib/mysqlになっています。データの保存先はMySQLの設定ファイル(/etc/my.cnf)から参照できます。
% docker container run --rm mysql:8.2.0 cat /etc/my.cnf | grep data
~ 省略 ~
datadir=/var/lib/mysql
~ 省略 ~
MySQLコンテナの起動
db-volumeをマウントしてMySQLコンテナを起動します。
% docker container run --name db1 --rm --detach --env MYSQL_ROOT_PASSWORD=secret --env MYSQL_DATABASE=sample --publish 3306:3306 --mount type=volume,source=db-volume,destination=/var/lib/mysql mysql:8.2.0
dd96d2f1a304a1ca2cf41f0ec2801c8321dd3ef65176426fc96cdb37402ae8c6
MySQLサーバーに接続します。そして、テーブルを作成し、いくつかデータを挿入してみましょう。
mysql % mysql --host=127.0.0.1 --port=3306 --user=root --password=secret sample
mysql> create table user (name varchar(32), email varchar(32));
Query OK, 0 rows affected (0.06 sec)
mysql> INSERT INTO user (name, email) VALUES ('Alice', 'alice@example.com'), ('Bob', 'bob@example.com');
Query OK, 2 rows affected (0.03 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from user;
+-------+-------------------+
| name | email |
+-------+-------------------+
| Alice | alice@example.com |
| Bob | bob@example.com |
+-------+-------------------+
2 rows in set (0.01 sec)
このデータは/var/lib/mysqlに保存されました。そして、それはボリュームがマウントしているので、コンテナ内ではなく、ボリュームにデータは保存されています。
ここでdb1コンテナを停止します。
docker container stop db1
db1のデータを引き継ぐ
新たにdb2コンテナを起動しましょう!db1コンテナにマウントしたdb-volumeをdb2でもマウントします。起動方法はdb1と同じですが、環境変数は今回はボリュームを利用するので不要です。なぜならdb1を起動する際にすでに作成されているからです。
% docker container run --name db2 --rm --detach --publish 3306:3306 --mount type=volume,source=db-volume,destination=/var/lib/mysql mysql:8.2.0
860f54f7d876dde1d768a34ec8820c92e870b749bce358c702bb7ace87c44dd1
ボリュームのおかげで、先程と接続情報は同じです。db2コンテナに、db1で追加したデータが有るか確認しましょう
% mysql --host=127.0.0.1 --port=3306 --user=root --password=secret sample
mysql> select * from user;
+-------+-------------------+
| name | email |
+-------+-------------------+
| Alice | alice@example.com |
| Bob | bob@example.com |
+-------+-------------------+
2 rows in set (0.01 sec)
db1コンテナのデータが消えずに引き継げていることが確認できました!
私も次からDockerでDBを構築するときは活用するようにしたいですね!