docker上のmysqlを使うにあたりよくあるパターン

しばらく時間が空くと忘れてしまうので備忘録。
dockerでmysqlサーバーを立てた時にありがちなパターンをまとめた。

今回はmysqlの公式イメージを使う前提。

起動時に初期データとユーザー追加

起動時にテーブルを作成したり、データを追加したい時、ユーザーを追加しておきたい時。
例えば、以下のようなユーザー追加と初期データ追加用のsqlファイルを任意のディレクトリ(今回はinit.dにしておく)に置いておき、

1
2
3
4
5
6
7
#! /bin/bash

CREATE_USER='mysql'
CREATE_PASSWORD='secret'
GRANT="GRANT ALL ON ${MYSQL_DATABASE}.* TO ${CREATE_USER}@'%' IDENTIFIED BY ${CREATE_PASSWORD}; FLUSH PRIVILEGES"

echo $GRANT | mysql -u ${MYSQL_ROOT_USER} -p${MYSQL_ROOT_PASSWORD}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DROP TABLE IF EXISTS `personal`;

CREATE TABLE `personal` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

LOCK TABLES `personal` WRITE;
/*!40000 ALTER TABLE `personal` DISABLE KEYS */;

INSERT INTO `personal` (`id`, `name`)
SELECT * FROM (SELECT 1, 'root@local') AS tmp
WHERE NOT EXISTS (
SELECT `id` FROM `personal` WHERE `id` = 1
) LIMIT 1;

これをイメージの/docker-entrypoint-initdb.d.sql.shファイルとして配置してやることで
コンテナ起動時する前に実行される。(Pull Request)

1
2
3
4
5
6
7
8
9
10
11
12
# Dcokerfile

FROM mysql
EXPORT '3306:3306'
ENV MYSQL_ROOT_USER root
ENV MYSQL_ROOT_PASSWORD root
ENV MYSQL_DATABASE sample_db
ENV MYSQL_USER test
ENV MYSQL_PASSWORD password

# 初期データをコンテナ起動時に実行
VOLUME ./init.d:/docker-entrypoint-initdb.d

データを永続化する

Dockerfile内でVOLUMEコマンドを使いホストのディレクトリをコンテナにマウントしてやることで永続化できる。
ポータビリティ(可搬性)を求める場合はデータを格納専用のコンテナを別途用意すると良い。

データ格納専用コンテナのディレクトリをデータベース用のコンテナにマウントすることで実現できる。
データ自体は永続化されているので、データベース用のコンテナな使い捨てできる。

データを格納専用のコンテナを作成は必要最小限の機能があればいいのでbusyboxとかでいい。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# データを格納専用のコンテナ
# -v でマウントするディレクトリ指定
docker run \
-d \
--name storage \
-v /var/lib/mysql \
busybox

# --volumes-from オプションで格納専用のコンテナを参照
docker run \
-d \
--name database \
--volumes-from storage \
-e MYSQL_ROOT_PASSWORD=root \
mysql

docker-inspectで詳細を見ると

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[
{
{
...
"Mounts": [
{
"Name": "1b3136bd545afa6d76427edd27408f47...",
"Source": "/mnt/sda1/var/lib/docker/volumes/1b3136bd545afa6d76427edd27408f47612ea1cd1f7a1857d810b24ecae2c16d/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "",
"RW": true
}
],
...
"Image": "mysql",
"Volumes": {
"/var/lib/mysql": {}
},
...
}
}
]

実体は /mnt/sda1/var/lib/docker/volumes/ にあるようだ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
docmer-machine ssh dev
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/
_ _ ____ _ _
| |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 1.9.1, build master : cef800b - Fri Nov 20 19:33:59 UTC 2015

sudo ls /mnt/sda1/var/lib/docker/volumes/1b3136bd545afa6d76427edd27408f47612ea1cd1f7a1857d810b24ecae2c16d/_data
auto.cnf ib_buffer_pool ib_logfile0 ib_logfile1 ibdata1 ibtmp1 mysql performance_schema sys

あった。

データをバックアップする

上記の方法で永続化したデータも、バックアップする必要があると思う。
この場合、データ格納専用コンテナのディレクトリとホストのディレクトリもマウントするコンテナを作成し、
データをホストディレクトに渡せばいいだけ。

1
docker run --rm --volumes-from database -v $(pwd):/backup busybox tar czvf /backup/archive.tar.gz /var/lib/mysql

ということで、開発環境やCI環境のコンテナ化の時にMySQL環境作成時に思い出そう。
今回使ったデータのまとめ

参考にしたページ

Docker の Data Volume まわりを整理する
Mount a host directory as a data volume

Comments