hidemium's blog

日々学んだことをアウトプットする。

DockerでMySQLを起動するDockerfileを書いてみた

Dockerfileを書く練習のため、今回は、sshdとMySQLの複数プロセスを起動するDockerfileを書いてみました。Dockerはプロセスを起動させるコマンドを1つしか指定できないため、プロセス管理ツールのSupervisorを使用しています。また、コンテナ内のデータベースファイルをホスト側に保存されるようにしてみました。

構成

Ubuntu 12.04: サーバ構築対象
Ubuntu 12.04はDocker 0.10上で動作しています。

Dockerfileの作成

Dockerfileを以下のように作成します。

$ mkdir -p docker/mysql
$ cd docker/mysql
$ vi Dockerfile
FROM ubuntu:12.04

MAINTAINER hidemium

# Ubuntu update
ADD sources.list /etc/apt/sources.list
RUN apt-get -y update

# Hack for initctl not being available in Ubuntu
RUN dpkg-divert --local --rename --add /sbin/initctl
RUN ln -sf /bin/true /sbin/initctl

# ssh install
RUN apt-get -y install openssh-server
RUN apt-get -y install python-setuptools
RUN easy_install supervisor
RUN mkdir -p /var/log/supervisor

# MySQL install
RUN apt-get install -y mysql-server
RUN apt-get clean

RUN mkdir /var/run/sshd
RUN echo 'root:root' | chpasswd

# sshd config
ADD id_rsa.pub /root/id_rsa.pub
RUN mkdir /root/.ssh/
RUN mv /root/id_rsa.pub /root/.ssh/authorized_keys
RUN chmod 700 /root/.ssh
RUN chmod 600 /root/.ssh/authorized_keys
RUN sed -i -e '/^UsePAM\s\+yes/d' /etc/ssh/sshd_config

# supervisor config
RUN mkdir -p /var/log/supervisor
ADD supervisord.conf /etc/supervisord.conf

# MySQL config
ADD mysql-listen.cnf /etc/mysql/conf.d/mysql-listen.cnf
RUN (/usr/bin/mysqld_safe &); sleep 3; mysqladmin -u root password 'passw0rd'; (echo 'grant all privileges on *.* to root@"%" identified by "passw0rd" with grant option;' | mysql -u root -ppassw0rd)

# Define mountable directories.
VOLUME ["/var/lib/mysql"]

# Expose ports.
EXPOSE 22 3306

# Define default command.
CMD ["supervisord", "-n"]
  • 「RUN dpkg-divert --local --rename --add /sbin/initctl」と「RUN ln -sf /bin/true /sbin/initctl」は、DockerでMySQLを使うためのハックのようです。詳しくはまだ理解できていません。。
  • 「RUN easy_install supervisor」は、apt-getでsupervisorのインストールができなかったため、easy_installにてインストールを行っています。
  • 「ADD supervisord.conf /etc/supervisord.conf」は、supervisorから起動するプロセスの定義ファイルを追加しています。
  • 「ADD mysql-listen.cnf /etc/mysql/conf.d/mysql-listen.cnf」はホスト側からMySQLへ接続できるように許可します。
  • 「RUN (/usr/bin/mysqld_safe &)~」はMySQLを一度起動して、パスワードの設定とホスト側からMySQLへ接続できるように許可します。
  • 「VOLUME ["/var/lib/mysql"]」はホスト側でマウントするディレクトリを指定します。

Dockerfileの中で、読み込みを行っているファイルは以下の通りです。

$ vi sources.list
deb http://jp.archive.ubuntu.com/ubuntu precise main restricted
deb-src http://jp.archive.ubuntu.com/ubuntu precise main restricted
deb http://jp.archive.ubuntu.com/ubuntu precise-updates main restricted
deb-src http://jp.archive.ubuntu.com/ubuntu precise-updates main restricted
$ vi mysql-listen.cnf
[mysqld]
bind = 0.0.0.0
$ vi supervisord.conf
[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D
autostart=true
autorestart=true

[program:mysqld]
command=/usr/bin/mysqld_safe
autostart=true
autorestart=true

Dockerの場合、MySQLの起動にservice mysql startが使えないため、/usr/bin/mysqld_safeで起動します。

MySQLコンテナの起動

以下のコマンドで、Dockerfileからビルドし、Dockerコンテナの起動を行います。
Dockerコンテナの起動時には、-vオプションを指定し、コンテナ内のデータベースファイルをホストのディレクトリに保存するようにしています。

$ sudo docker build -t ubuntu-mysql .
$ sudo docker run -d -p 22 -p 3306 -v /opt/mysql/data:/var/lib/mysql --name ubuntu-mysql ubuntu-mysql

mysqld_safeで起動しているため、ビルドするときに以下のエラーが出ることがあります。

140522 18:26:08 mysqld_safe Can't log to error log and syslog at the same time.  Remove all --log-error configuration options for --syslog to take effect.
140522 18:26:08 mysqld_safe Logging to '/var/log/mysql/error.log'.
140522 18:26:08 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql

Dockerコンテナの3306番ポートにフォワードしているポート番号を確認し、ホスト側からMySQLに接続できることを確認します。
Dockerfileで外部から接続する許可を行っているため、コンテナの起動直後からMySQLにログインできます。

$ sudo docker port ubuntu-mysql 3306
0.0.0.0:<ポート番号>
$ mysql -uroot -h 127.0.0.1 -P <ポート番号> -ppassw0rd