DockerでMySQLを動かす

Dockerでデーモンを動かそうとするとinitctlがうまく動かないので、service start mysqlとか出来ないんです。だから直接mysqld_safeを起動するのですが、baseイメージからDockerfileでインストールすと、簡単にインストールできない。というのも、apt-get install mysql-serverしたときにいろいろオプションを対話的に入力しろといわれるので、Dockerfileで素直には出来ないんです。

いろいろ調べてみると、そういったパラメタをあらかじめ設定してインストールする方法があって、debconf-set-selectionsというコマンドがそれに相当するみたいです。もっと簡単にできる方法を id:nkwhr さんに教えてもらいました。DEBIAN_FRONTEND=noninteractiveと環境変数に設定すればいいみたいです。下記のスクリプトは修正済みです。また普通にapt-getすると設定ファイルがあるよとダイアログが表示されてしまうので、これも抑制したい。これにはdpkgに--force-confoldというオプションがあってこれを指定すると古いファイルをそのまま使うようにあらかじめ設定しておけます。また、apt-getにはdpkgに引数を渡すことが出来る仕組みがあったのでこれ経由で引数を渡します。

From ubuntu:quantal

# my.cnfをコピー。 Dockerfileのディレクトリにmy.cnfファイルをおいておく必要があります
ADD my.cnf /etc/mysql/my.cnf

# security updateを追加
RUN echo "deb http://us.archive.ubuntu.com/ubuntu/ quantal-updates main restricted" >> /etc/apt/sources.list
RUN echo "deb-src http://us.archive.ubuntu.com/ubuntu/ quantal-updates main restricted" >> /etc/apt/sources.list
RUN apt-get update

# /sbin/initctlが原因でmysql-serverが起動しない問題へのhack
RUN dpkg-divert --local --rename --add /sbin/initctl
RUN ln -s /bin/true /sbin/initctl

# my.cnfは上書きしない
RUN apt-get install -y -o Dpkg::Options::="--force-confold" mysql-common
RUN DEBIAN_FRONTEND=noninteractive apt-get install -q -y mysql-server
# passwordなしでリモートからrootでログインできるようにする
RUN (/usr/bin/mysqld_safe &); sleep 3; echo "grant all privileges on *.* to root@'%';" | mysql -u root -ppassword

EXPOSE 3306

CMD ["/usr/bin/mysqld_safe"]

my.cnfは下記の通り

[client]
port            = 3306
socket          = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket          = /var/run/mysqld/mysqld.sock
nice            = 0

[mysqld]
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
key_buffer              = 16M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
query_cache_limit       = 1M
query_cache_size        = 16M
log_error = /var/log/mysql/error.log
expire_logs_days        = 10
max_binlog_size         = 100M

[mysqldump]
quick
quote-names
max_allowed_packet      = 16M
[mysql]

[isamchk]
key_buffer              = 16M

!includedir /etc/mysql/conf.d/

これでmysqlのイメージは作ることが出来ます。

sudo docker build -t="cpw/mysql" .

あとは以下のコマンドを実行してmysql-serverを実行できます。

$ sudo docker run -d cpw/mysql
3ec822a71a3a
$ sudo docker port 3ec822a71a3a 3306
49289
$ mysql -u root -h 172.16.35.134 -P 49289

データを永続化したい

上記の手順だけだとデータが永続化されません。Dockerでコンテナからホストのディレクトリをマウントすると組み合わせて設定をすると永続化することも可能です。下記のようにしてホストマシンのディレクトリをコンテナのディレクトリにマウントします。初めてマウントした状態だとDBは存在しない状態なので、一度コンテナからDBを作成します。

$ sudo run docker run -v /var/docker/mysql:/var/lib/mysql -i -t cpw/mysql /bin/bash
root@048a4c9afd4e:/# mysql_install_db 
root@048a4c9afd4e:/# mysqld_safe &
root@048a4c9afd4e:/# echo "grant all privileges on *.* to root@'%';" | mysql -u root 
root@048a4c9afd4e:/# exit
$ sudo docker run -v /var/docker/mysql:/var/lib/mysql -d cpw/mysql
$ sudo docker port ca9f3b7fc39b 3306
49292
$ mysql -u root -h 172.16.35.134 -P 49292