初期化されたMySQLのDockerコンテナを用意する

サーバーサイドアプリケーションの開発環境などにおいて、「初期化された(データベースやテーブルが作成された)MySQLのDockerコンテナを用意したい」といった場面があると思います。そういった際にどうすればよいか、簡単な例を通して説明します。

コード

init.sql

実行したいSQL文たちをファイルとして保存します。

CREATE DATABASE db1;
USE db1;
CREATE TABLE table1(id INT);
INSERT INTO table1 VALUES(1);

Dockerfile

SQL文が書かれたファイルを /docker-entrypoint-initdb.d/ ディレクトリ下にもってきます。MySQLのDockerオフィシャルイメージにおいて、このディレクトリ下に置かれたファイル内に記載されたSQL文がデータベース起動時に実行されるようになっています。

ここでは、2019/4/8現在最新の mysql:8.0.15 イメージを用いています。

FROM mysql:8.0.15
COPY init.sql /docker-entrypoint-initdb.d/init.sql

実行

Dockerファイルとinit.sqlが存在しているディレクトリ内で以下のコマンドを実行します。

$(docker build . -q) はDockerファイルをもとにイメージを作成し、イメージのIDを返しています。そしてそのイメージをもとにコンテナを立ち上げています。簡単のために、 -e MYSQL_ALLOW_EMPTY_PASSWORD=1 によってパスワードを無効化しています。

$ docker run -d -e MYSQL_ALLOW_EMPTY_PASSWORD=1 $(docker build . -q)

確認

データベース内にアクセスして確認してみます。

$ docker exec -ti <コンテナ名> mysql
mysql> select * from db1.table1;
+------+
| id   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

うまく初期化され、データが入っていることがわかります。

複数ファイルに分割したい場合

今回はSQL文が書かれたファイルを1つ用意しましたが、わかりやすさのためにこれを複数に分けたい場合もあると思います(テーブルの作成とダミーデータの挿入を分けるなど)。そういった際には、init001.sql, init002.sql ... といったようにファイルを分割し、それらを /docker-entrypoint-initdb.d/ 以下に持ってくれば大丈夫です。辞書順で実行してくれます。