見出し画像

データ保存用のDocker Containerをdocker-composeで管理する

Docker Containerが立ち上げ済みのとき、すでにデータが用意されているDocker Containerがあると便利だ、と思う場面がある。例えば

- テスト用のデータをテスト開始時に用意するコストを避けたい
- とりあえずアプリを立ち上げて試す状態にしたい

など。手順として以下の流れを踏む。

1. データをインポートした状態のDocker Imageを作成
2. Docker Hubにアップロードを行う
3. Docker Hubから取得したDocker ImageよりDocker Containerを作成
4. Docker ContainerのVolumeに対して特定のファイルシステムを他のDocker Containerと共有するように設定
5. 他のDocker Containerがデータ用のDocker Containerとデータを共有

データをインポートした状態のDocker Imageを作成する

例として、MySQL上のテーブルに対しすでにデータが用意されているDocker Imageを作成する手順を紹介する。作成のヒントはこちらのエントリを参考にした。特に、データを保存するDocker Imageの作成手順はDockerでデータ入りのMySQLボリュームイメージをつくるのエントリを参考にしている。知見を共有していただき感謝しています。m(_ _)m

MySQLのDocker Containerを作成し、初期データを入れ込む作業を実施する。

こちらのエントリと同じ手順を踏み、MySQLでのDocker containerを立ち上げる。

docker run -d --name db \
  -e 'MYSQL_ALLOW_EMPTY_PASSWORD=yes' \
  -p 3306:3306 mysql:latest

立ち上げ後、データのインポートをDocker containerに対して行う。例として、CREATE DATABASE, CREATE TABLE, INSERT文すべてを実行するSQLファイルを用意した。SQLファイルを利用し、MySQLデータベースの初期化を行う。

curl https://gist.githubusercontent.com/futoase/cc7fc96ca9d4b6e07e9e85648d18ca03/raw/e6bcbc682935b565406891db37309f21f0221c87/create_test_db.sql | \
  mysql -h 127.0.0.1 -uroot

DB及びテーブルが作成されたか確認をする。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test_db            |
+--------------------+
5 rows in set (0.00 sec)

mysql> show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| users             |
+-------------------+
1 row in set (0.01 sec)

mysql> select * from users;
+----+----------+-----+-----+
| id | name     | age | sex |
+----+----------+-----+-----+
|  1 | taro     |  18 |   1 |
|  2 | jiro     |  17 |   1 |
|  3 | hanako   |  21 |   2 |
|  4 | himawari |  20 |   2 |
+----+----------+-----+-----+
4 rows in set (0.00 sec)

その後、MySQL Docker ContainerのVolumeをホストマシンにcopyする。こちらのエントリと同じ操作を行う。

> mkdir -p ./data/var/lib
> docker cp db:/var/lib/mysql ./data/var/lib
> ls ./data/var/lib/mysql/
auto.cnf           binlog.index       client-cert.pem    ib_logfile0        ibtmp1             performance_schema server-cert.pem    test_db
binlog.000001      ca-key.pem         client-key.pem     ib_logfile1        mysql              private_key.pem    server-key.pem     undo_001
binlog.000002      ca.pem             ib_buffer_pool     ibdata1            mysql.ibd          public_key.pem     sys                undo_002

ホストマシンへのデータコピーを終えたのを確認した後、BusyBoxベースのDocker Imageを作成する。VOLUME命令にて、MySQLがデータ保存に利用するパスを指定する。こちらのエントリと同じ操作を行う。

FROM busybox
RUN mkdir -p /var/lib/mysql
COPY data/var/lib/mysql /var/lib/mysql
RUN chown -R 999:999 /var/lib/mysql
VOLUME /var/lib/mysql
CMD tail -f /dev/null

ホストマシンのMySQLデータをコピーしたディレクトリ上Dockerfileに上記内容を記述し、docker buildを実行する。

docker build . -t db_storage:latest

作成したdocker imageについて作成が行えたか確認をする

docker images | grep db_storage
db_storage  latest  3aa4448e1be7  14 seconds ago 371MB

docker-composeで、Docker Containerの管理を行う

ここは、docker-compose version 3の形式で記述する。MySQL Containerと、作成したstorage用container のリンクを行う。

version: '3'
services:
 mysql_db:
   image: db_storage:latest
   volumes:
     - dbdata:/var/lib/mysql
 mysql:
   image: mysql:latest
   environment:
     - MYSQL_ALLOW_EMPTY_PASSWORD=yes
   volumes:
     - dbdata:/var/lib/mysql
   ports:
     - 3306:3306
volumes:
 dbdata:

docker-compose.ymlとして保存し、docker-compose upを実行する。

docker-compose up

docker-composeで立ち上げたMySQL Docker Containerに接続を行い、DBやテーブルの状態を確認する。

mysql -h 127.0.0.1 -uroot
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test_db            |
+--------------------+
5 rows in set (0.00 sec)
mysql> use test_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| users             |
+-------------------+
1 row in set (0.01 sec)
mysql> select * from users;
+----+----------+-----+-----+
| id | name     | age | sex |
+----+----------+-----+-----+
|  1 | taro     |  18 |   1 |
|  2 | jiro     |  17 |   1 |
|  3 | hanako   |  21 |   2 |
|  4 | himawari |  20 |   2 |
+----+----------+-----+-----+
4 rows in set (0.00 sec)

これで、データが既に初期化されたDocker imageを作成することができた。

記事を読んでいただき、ありがとうございます。うれしいです😊