【dockerのmysql公式イメージの使い方】初期データ投入やユーザ作成、文字コード指定などのカスタマイズ方法

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」は、コンテナ起動の元になるイメージ名です。

いろいろなカスタマイズ

さて、公式イメージはいろいろカスタマイズが可能だと言いましたが、その方法をご紹介します。

Mysqlのバージョンを指定する

「FROM mysql:5.7.21」で使用するmysqlのバージョンを指定しています。

特にこだわりがない場合は、「mysql:latest」で最新版を取得してもいいかもしれませんが、指定しておいた方が安全かもしれません。

DBの文字コードを変更する

公式のイメージではデフォルトの文字コードが「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_USERMYSQL_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