user icon

Docker公式イメージで開発用RDBをゲットだぜ(MySQL編)

まえがき

Docker公式イメージで開発用RDBをゲットだぜ(PostgreSQL編)

に続きMySQL編です。Docker for Macを使用しております。はじめるよ〜。

MySQL

Dockerの公式MySQLイメージの使い方を徹底的に解説するよ

という素敵なページがありましたのでこちらも参考にさせていただこうと思います。

公式イメージを調べる

OFFICIAL REPOSITORY mysql

2016年8月中旬現在、以下のバージョンがあるようです。

5.7(5.7.14), 5.6(5.6.32), 5.5(5.5.51)

少ない気もしますが覚悟を決めて5.5以上で行きましょう。「古いMySQL死すべし」という意思を感じます。

起動する

latestは5.7系のようですので、あえて5.5系ですすめてみます。

$ docker run -d --name mysql55 -e MYSQL_ROOT_PASSWORD=mysecretpassword -p 13306:3306 mysql:5.5

公式の例を参考にコンテナの3306を13306にポートフォワードしています。

接続する

mysqlコマンドで接続します。公式の例はクライアントコンテナでenvの情報を利用して一気につなぐ方法ですね。

$ docker run -it --link mysql55:mysql --rm mysql:5.5 sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.51 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

mysql> select Host, User from mysql.user;
+------+------+
| Host | User |
+------+------+
| %    | root |
+------+------+
1 row in set (0.00 sec)

mysql> exit
Bye

便利だけど長い〜。シェルスクリプトにでもしておくのがよいでしょうか。clientというファイルに書いて実行権限を付けておきます。

$ ./client 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.5.51 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

おけおけ。PostgreSQLの方にも作っておこうかな。

次に Sequel Pro 先生で繋いでみます。13306にポートフォワードしてますので

Sequelで接続(接続情報)

サクッと繋がりました。

Sequelで操作

mysqlデータベースの中など覗いてみたり。楽ちん。

設定ファイルなど

コンテナのシェルを起動して探検してみます。

$ docker exec -it mysql55 bash  

とりあえずmy.cnfを眺めてみる。

root@688eab40f1a8:/# more /etc/mysql/my.cnf
[mysqld]
skip-host-cache
skip-name-resolve
datadir = /var/lib/mysql
!includedir /etc/mysql/conf.d/

/etc/mysql/conf.d/ のcnfファイルを読み込むようになっていますね。

拡張する

いろいろな方法が用意されているようです。

まず、先ほど調べたようにコンテナの /etc/mysql/conf.d/ にcnfファイルを置くと読み込まれます。

PostgreSQLの公式イメージと同じくコンテナの /docker-entrypoint-initdb.d に拡張子がsh、sql、sql.gzのファイルを置くとコンテナ起動時に実行してくれます。mysql/5.5/docker-entrypoint.shを眺めてみたところ、

for f in /docker-entrypoint-initdb.d/*; do
    case "$f" in
        *.sh)     echo "$0: running $f"; . "$f" ;;
        *.sql)    echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
        *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
        *)        echo "$0: ignoring $f" ;;
    esac
    echo
done

このように仕組みも同じ感じでした。

他、PostgreSQLの時と同じように日本語化されたイメージを作ろうと思います。

日本語化されたイメージの作成

PostgreSQLでのやり方を参考にdefault localeを設定するDockerfileを作ります。

Dockerfile

FROM mysql:5.5

MAINTAINER murave

RUN apt-get update && apt-get install locales -y && localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8

公式イメージにはlocalesが入っていなかったのでlocaledefの前にapt-getで導入するようにしました。

日本語化されたイメージ、mysql_jp:5.5を作ります。

$ docker build -t mysql_jp:5.5 ./

確認

$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
mysql_jp             5.5                 42465a1c94d5        22 minutes ago      284.5 MB

設定ファイルの調整

/etc/mysql/conf.d/ にバインドするディレクトリconf.dを作成して追加の設定を書いたcnfファイルを置きます。

conf.d/custom.cnf

[mysqld]
character-set-server=utf8

Mac上のcond.dディレクトリを/etc/mysql/conf.dにバインドするようにオプションを付けて起動します。

$ docker run -d --name mysql55  -e MYSQL_ROOT_PASSWORD=mysecretpassword -p 13306:3306 -v $(pwd)/conf.d/:/etc/mysql/conf.d mysql_jp:5.5

execでコンテナ上の/etc/mysql/conf.dのls結果を見てバインドされているか確認。

$ docker exec -it mysql55 ls /etc/mysql/conf.d
custom.cnf

おけおけ。

データベースの初期化

アカウント、データベース作成は設定用に準備された環境変数(MYSQL_USER、MYSQL_PASSWORD、MYSQL_DATABASE)を利用し、/docker-entrypoint-initdb.d ディレクトリのスクリプト実行を利用してテーブル作成などをしてみたいと思います。

ユーザーをfoo、データベースをfoodbとする前提で初期化用のsqlファイルを作ります。
initdb/01createtable.sql

CREATE TABLE foodb.users (id int , name varchar(255));
GRANT ALL ON foodb.users TO foo;
INSERT INTO foodb.users (id, name) VALUES (1, 'first'), (1, 'second')

foodbデータベースにusersテーブルを作成しユーザーfooに権限を与え、usersテーブルに初期値をINSERT文で投入というシナリオです。

/docker-entrypoint-initdb.d をバインドして起動。

$ docker run -d --name mysql55 -e MYSQL_DATABASE=foodb -e MYSQL_USER=foo -e MYSQL_PASSWORD=foopassword -e MYSQL_ROOT_PASSWORD=mysecretpassword -p 13306:3306 -v $(pwd)/conf.d/:/etc/mysql/conf.d -v $(pwd)/initdb/:/docker-entrypoint-initdb.d mysql_jp:5.5

確認します。

$ ./client 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.51 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| foodb              |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)

mysql> select Host, User from mysql.user;
+------+------+
| Host | User |
+------+------+
| %    | foo  |
| %    | root |
+------+------+
2 rows in set (0.00 sec)

mysql> USE foodb;
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_foodb |
+-----------------+
| users           |
+-----------------+
1 row in set (0.01 sec)

mysql> SELECT * from users;
+------+--------+
| id   | name   |
+------+--------+
|    1 | first  |
|    1 | second |
+------+--------+
2 rows in set (0.00 sec)

mysql> exit
Bye

想定通りに初期化されているようです。

スクリプト実行についての悲しい補足情報

はじめはsqlファイルではなくshファイル(シェルスクリプト)内でmysqlコマンドを呼び出して初期化しようとしていました。実際に使用するユーザーでテーブル作成やデータ投入したいじゃないですか。気分的に。

initdb/01createtable.sh

!/bin/bash
set -e

mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" $MYSQL_DATABASE <<-EOSQL
    CREATE TABLE users (id int , name varchar(255));
EOSQL

このようなスクリプトでテーブル作成は行われるのですがshスクリプト実行後にコンテナがExitしてしまうという症状が発生。解決出来ずにハマりまくり、sqlファイルでの初期化に方針変更しました。

その後、落ち着いて公式イメージのページを見なおしていると

No connections until MySQL init completes

という項目があるのに気付きました。mysqlコマンドで接続しているのが原因っぽいですね。

Docker Compose で開発用の MySQL を起動する

日本語化したイメージを使用しconf.dのcnfファイルで設定調整、initdbのスクリプトで初期化、データの永続化はbusyboxを使用する方針でdocker-compose.ymlを作成します。

docker-composeでmysql & postgreSQL をサクッと起動

を参考にさせていただきました。

docker-compose.yml

datastore:
  image: busybox
  volumes:
    - /var/lib/mysql
  container_name: mysql-datastore

mysql:
  image: mysql_jp:5.5
  environment:
    MYSQL_ROOT_PASSWORD: mysecretpassword
    MYSQL_USER: foo
    MYSQL_PASSWORD: foopassword
    MYSQL_DATABASE: foodb
  volumes:
    - ./conf.d/:/etc/mysql/conf.d
    - ./initdb/:/docker-entrypoint-initdb.d
  ports:
    - "13306:3306"
  volumes_from:
    - datastore
  container_name: mysql-db

起動します。

$ docker-compose up -d        
Creating mysql-datastore
Creating mysql-db

以降、使用するあいだはstop・startで停止・起動。

mysqlコマンドでの接続用のclientスクリプトのコンテナ名をmysql-dbに修正して接続して動作を確認。
Sequel Pro を使いポートフォワードした13306にユーザーfooでfoodbデータベースに接続しての操作もできました。

ディレクトリファイル構成は以下のようになりました。

.
├── Dockerfile
├── client
├── conf.d
│   └── custom.cnf
├── docker-compose.yml
└── initdb
    └── 01createtable.sql
Facebooktwitterlinkedintumblrmail

タグ: ,

名前
E-mail
URL
コメント

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)