2017/02/24更新

[Docker] 公式MySQLイメージを使って、使い捨てのDB環境を構築する

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
今日はDocker Hubで公開されている公式MySQLイメージを使って、ローカル環境にDB環境を構築する方法をブログに書きたいと思います。
画像

目次




イメージの入手

Docker Hubで公開されている公式MySQLイメージからDockerのイメージを入手できます。ここではバージョンにこだわりはないので、latest(執筆時はv5.7)を使いたいと思います。
# MySQL のイメージを Docker Hub から入手します
$ docker pull mysql:latest

# ダウンロードされたことを確認します
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               latest              7666f75adb6b        3 weeks ago         406 MB
これでイメージ入手ができました。



コンテナの作成と起動

コンテナの作成にはdocker runを使います。ここで環境変数を指定することで、色々と設定することができます。詳細は「Environment Variables」に記載があります。
# MySQLイメージからコンテナを作成します.
# ここでは以下の値を指定しています。
#   rootのパスワード:secret
#
# また、ポートフォワーディングとして、33306 → 3306 に設定しています。
$ docker run \
    --name my-mysql \
    -e MYSQL_ROOT_PASSWORD=secret \
    -p 33306:3306 \
    -d mysql:latest

# 起動したことを確認します
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
3e461fe3faa4        mysql:latest        "docker-entrypoint..."   2 days ago          Up 3 seconds        0.0.0.0:33306->3306/tcp   my-mysql
また、-dオプションをつけてデーモン起動するところもポイントです。
これでコンテナは起動しましたが、中のMySQLが初期化されるまで数分時間がかかります。少し待ってから接続確認を行います。
# mysqlクライアントから接続確認を行います。
# ローカル環境で3306ポート以外に接続するには、--hostオプションが必要です(つけないとポーと指定が無視される)。
# または、--hostの代わりに--protocol=TCPオプションでもポート指定が有効になります。

# まだMySQLが初期化中だと以下のエラーになります。
# エラーになったら少し待ちます.
$ mysql -uroot -psecret --port=33306 --host=127.0.0.1
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

# 初期化完了後には接続できます。
$ mysql -uroot -psecret --port=33306 --host=127.0.0.1
mysql>
これで無事に接続できました。



別のコンテナから接続する

別のコンテナから接続するには、--linkでコンテナを紐づけることで接続することができます。
# 別のコンテナを作成して、--link オプションでMySQLのコンテナへ接続します.
$ docker run --name myapp -it --rm --link my-mysql:mysql mysql:latest /bin/bash
root@552e5397eaa1:/# 

# env にMySQLへ接続する情報が入っています.
root@552e5397eaa1:/# env
HOSTNAME=552e5397eaa1
MYSQL_ENV_MYSQL_ROOT_PASSWORD=secret
TERM=xterm
MYSQL_VERSION=5.7.17-1debian8
MYSQL_ENV_GOSU_VERSION=1.7
MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_PORT_3306_TCP=tcp://172.17.0.2:3306
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
MYSQL_ENV_MYSQL_VERSION=5.7.17-1debian8
MYSQL_ENV_no_proxy=*.local, 169.254/16
HOME=/root
SHLVL=1
MYSQL_PORT_3306_TCP_PROTO=tcp
MYSQL_NAME=/myapp/mysql
no_proxy=*.local, 169.254/16
MYSQL_MAJOR=5.7
MYSQL_PORT_3306_TCP_ADDR=172.17.0.2
GOSU_VERSION=1.7
MYSQL_ENV_MYSQL_MAJOR=5.7
MYSQL_PORT=tcp://172.17.0.2:3306
_=/usr/bin/env

# それら情報を使って接続します.
$ mysql -uroot -p${MYSQL_ENV_MYSQL_ROOT_PASSWORD} -h${MYSQL_PORT_3306_TCP_ADDR} 
mysql> 
これで、別コンテナからも接続ができました。



設定ファイル(*.cnf)を追加で指定する

コンテナ起動時にMySQLの設定ファイルを指定したい場合には、ディレクトリ共有を用います。コンテナ内の/etc/mysql/conf.dに、独自のcnfファイルを置くことで、それを読み込んでくれます。
# 以下の設定ファイルを読み込むことにします.
$ cat /tmp/mysql/conf/custom.cnf
[mysqld]
character-set-server=utf8mb4

# 上記のファイルをディレクトリ共有でコンテナに渡します.
# -v オプションを利用します.
docker run \
    -v /tmp/mysql/conf:/etc/mysql/conf.d \
    --name my-mysql \
    -e MYSQL_ROOT_PASSWORD=secret \
    -d -p 33306:3306 mysql:latest

# 接続して確認すると、設定が反映されていることがわかります.
$ mysql -uroot -psecret --port=33306 --host=127.0.0.1
mysql> show variables like "%character_set%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)



初期化時に実行する処理を指定する

コンテナ起動時に処理を実行することができます。コンテナ内の/docker-entrypoint-initdb.d*.sh*.sqlファイルを置くとそれらが実行されます。
# 今回は、Users テーブルを作成します.
# その他にユーザー作成や初期データ投入なども行うことに使えます.
$ cat /tmp/mysql/init-data/init.sql 
CREATE TABLE users (id int, name varchar(255));

# 初期実行ファイルをディレクトリ共有でコンテナに渡します.
# またここでは、 MYSQL_DATABASE を環境変数に指定して、 myapp というデータベースも作成しています.
$ docker run \
    -v /tmp/mysql/init-data:/docker-entrypoint-initdb.d \
    --name my-mysql \
    -e MYSQL_ROOT_PASSWORD=secret \
    -e MYSQL_DATABASE=myapp \
    -d -p 33306:3306 mysql:latest

# テーブルができていることを確認できます.
$ mysql -uroot -psecret --port=33306 --host=127.0.0.1
mysql> use myapp;
mysql> show tables;
+-----------------+
| Tables_in_myapp |
+-----------------+
| users           |
+-----------------+
1 row in set (0.00 sec)
これで初期処理の実行を行うことができました。



参考資料

以下の Docker Hub の説明がよくわかりました。ありがとうございます。
https://hub.docker.com/_/mysql/



最後に

MySQL環境も簡単に作っては壊しができるのはいいですね。様々な検証が簡単にできて嬉しい限りです。Dockerについてはもっともっと触っていこうと思います。

最後になりますが本ブログでは、Linux・Node.js・Python・フロントエンド・インフラ・Go言語・開発関連・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSTwitterをフォローして頂けると幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。