dockerで初期データ投入済みのmysql環境を用意するときのTipsです。
初期データや初期ユーザのセットアップが完了したMysqlDBを作るには、大きく2つの方法があります。
一つは公式のdockerイメージを使って、カスタマイズする方法、もう一つは、自分でlinuxのイメージなどにmysqlをインストールしてシェルなどで初期データ投入などを行うする方法 です。
公式イメージはカスタマイズしやすく出来ていますので、大抵のことはこれでできると思います。
- 初期データ投入
- 初期ユーザ作成
- 文字コードなどcnfファイルで設定できるもの
などをカスタマイズできます。
この記事では、公式イメージの使い方を説明します。
docker公式イメージを使って初期データセットアップ済のMysqlを用意する
まずは、シンプルなDockerfileをご紹介します。
これをひな形に、いろいろな初期セットアップをしていくことができます。
FROM mysql:5.7.21
COPY Dump_db.sql /docker-entrypoint-initdb.d/
EXPOSE 3306
このDockerfileを使って、
docker build --no-cache -t myimg/mysql:1.0 .
のようにBuildすると、イメージができます。(–no-cacheは任意)
ファイルの中でCOPY
している「Dump_db.sql」は初期データを投入しているので、シンプルにDBを起動したいだけなら、この行はコメントアウトしてOKです。
カスタマイズする場合は、このファイルも作成して、Dockerfileと同じディレクトリに配置します。
Dump_db.sqlの中身は以下のような感じ。一行目にuse test_db;
がありますが、このDB「test_db」は、後程、コンテナをrunするときに環境変数として渡して、作成しています。
use `test_db`;
DROP TABLE IF EXISTS `sample1`;
CREATE TABLE `sample1` (
`id` int(7) NOT NULL,
`title` varchar(256) NOT NULL,
PRIMARY KEY (`id`)
) ;
LOCK TABLES `sample1` WRITE;
INSERT INTO `sample1` VALUES (1,'title1');
UNLOCK TABLES;
Mysqlコンテナをrunしてみる
用意ができたら、コンテナを起動します。
コマンドは
docker run --name con-mysql \
-e MYSQL_ROOT_PASSWORD=test_pw -e MYSQL_DATABASE=test_db \
-p 33306:3306 -d myimg/mysql:1.0
のような感じです。
少し上記コマンドに渡しているオプションの解説をしましょう。
--name con-mysql
で起動するコンテナ名を指定しています。
また、-e
で環境変数を渡すことができます。
公式のイメージに渡すことができる環境変数は、公式ページの
「https://hub.docker.com/_/mysql/#environment-variables」
に記載があります。
MYSQL_ROOT_PASSWORD
はrootのパスワードなので、必須ですね。
また、MYSQL_DATABASE
で初回起動時に「test_db」という名前のDBを作成してくれます。初期データを投入したい場合は必要になります。
-p 33306:3306
は、-p <ホストPC側のポート>:<dockerコンテナ内部のポート>
の形式で指定します。
この例だと、dockerコンテナの3306番で動いているポートにホストPCから33306番のポートで接続できるように、コンテナを起動するというオプションです。
Dockerfileの最後にEXPOSE 3306
という行があることに気を付けてください。
この命令でdockerのコンテナの3306番を「公開」はしていますが、-p 33306:3306
でホスト側へポートフォワードしないとコンテナの外からは接続できません。
起動はしたけど、接続できない!という場合に確認する方法はこの記事に書きました。
-d
も重要です。このコンテナをデーモンモードで起動します。
最後の「myimg/mysql:1.0」は、コンテナ起動の元になるイメージ名です。
いろいろなカスタマイズ
さて、公式イメージはいろいろカスタマイズが可能だと言いましたが、その方法をご紹介します。
「FROM mysql:5.7.21」で使用するmysqlのバージョンを指定しています。
特にこだわりがない場合は、「mysql:latest」で最新版を取得してもいいかもしれませんが、指定しておいた方が安全かもしれません。
公式のイメージではデフォルトの文字コードが「latin1」になっており、日本語環境だと使いにくいので、変更します。
公式イメージでは設定ファイルとしてコンテナ内の「/etc/mysql/my.cnf」が使われていますが、「.cnf」という拡張子のファイルを /etc/mysql/conf.d または /etc/mysql/mysql.conf.d 配下に置くと、カスタマイズできます。
DockerfileにCOPY my.cnf /etc/mysql/conf.d/
と記述すると、自分で追加の設定を行った「my.cnf」という名前のファイルをコンテナの「/etc/mysql/conf.d/」ディレクトリ配下に配置できます。
my.cnfの中身はこんな感じ。
[mysqld]
default_authentication_plugin = mysql_native_password
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
character-set-server=utf8mb4
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
先程、環境変数が出てきましたが、これを使うと、初回起動時にrootとは別にもう一つ、ユーザを作成できます。
環境変数、MYSQL_USER
とMYSQL_PASSWORD
を使います。
docker run --name con-mysql \
-e MYSQL_ROOT_PASSWORD=test_pw -e MYSQL_DATABASE=test_db\
-e MYSQL_USER=user1 -e MYSQL_PASSWORD=user1_pass \
-p 33306:3306 -d myimg/mysql:1.0
のように使います。
これで、初回起動時にuser1がuser1_passというパスワードで作成されます。
上記で出てきた「Dump_db.sql」を使うと、初期データの投入ができます。
実は公式イメージでは、コンテナ側の「/docker-entrypoint-initdb.d/」というディレクトリに「*.sql」「*.sh」「*.sql.gz」という拡張子のファイルを配置しておくと、初回起動時に実行してくれます。
上記の「Dump_db.sql」例だと、テーブルの作成とデータ投入を行ってくれるんですね。
このファイルの実行は、ファイル名の昇順に行われます。そのため「1.create_another_db.sql」「2.Dump_db.sql」のようなファイルを配置しておくと、番号の若い順に実行されます。
「1.create_another_db.sql」の中で、以下のようにユーザ作成や権限付与なども行うことができるので、環境変数だけでは対処できない、複数のテーブルやユーザ作成などを行う際には重宝すると思います。
CREATE DATABASE IF NOT EXISTS sample_tbl2;
CREATE USER 'test_user2'@'%' identified by 'test_pass2';
GRANT ALL ON sample_tbl2.* TO 'test_user2'@'%' ;
use `test_db`;
DROP TABLE IF EXISTS `sample1`;
CREATE TABLE `sample1` (
`id` int(7) NOT NULL,
`title` varchar(256) NOT NULL,
PRIMARY KEY (`id`)
) ;
LOCK TABLES `sample1` WRITE;
INSERT INTO `sample1` VALUES (1,'title1');
UNLOCK TABLES;
FROM mysql:5.7.21
COPY my.cnf /etc/mysql/conf.d/
COPY 1.create_another_db.sql /docker-entrypoint-initdb.d/
COPY 2.Dump_db.sql /docker-entrypoint-initdb.d/
EXPOSE 3306