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