Intelligent Technology's Technical Blog

株式会社インテリジェントテクノロジーの技術情報ブログです。

DockerでApache+PHP+mysql

櫻です。

最近Dockerが流行の様なので少し触ってみました。
使い捨てに出来る環境が数秒で起動出来るのは素晴らしいですね。

supervisorで起動する方式のコンテナの作成方法(Dockerfileの書き方)のメモです。
CentOS6.5のコンテナが出来上がります。

環境など

docker 0.8からMacから操作出来る様になっているのですが、docker buildする毎にUploading contextの容量が以上に大きくなっていったのでMacから直接操作するのは諦めてCentOS6.5でコンテナの作成は行いました。
一つのコンテナ内で複数のサーバ起動する場合はsupervisorを使うのがお手軽らしいため、supervisorにお任せしています。CentOSではepelにパッケージがあるのですが、これを利用したところCPUの使用率が100%になったため、easy_installでインストールできるバージョンを利用しました。

ホスト

コンテナを動作させる環境はboot2docker等を利用すれば良いのですが、Dockerfileの作成中はコンテナと同じLinuxを利用するとパッケージ名などが調べやすいと思います。ということでまずはCentOSにdockerをインストールします。epelにdockerが追加されているため、yumでインストールする事が可能です。

$ sudo yum install http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install docker-io
$ sudo service docker start
$ sudo gpasswd -a `whoami` docker

注意点はパッケージ名がdocker-ioという事くらいでしょうか。(dockerだと別の物がインストールされます)
最後に自分をdockerグループに追加しています。これを省略するとdockerコマンドを実行する際に毎回sudoが必要になります。(グループを反映するために、再ログインが必要かもしれません)

$ docker version

でバージョン情報が表示されればOKです。

Dockerfile

dockerのインストールが出来たので、コンテナ(Dockerfile)の作成に入ります。
CentOSのコンテナを作成するため、FROMはcentosを指定しています。プロキシを利用している環境であれば、その指定もしておきます。

FROM centos
MAINTAINER ...

ENV http_proxy http://proxy.example.com
ENV https_proxy http://proxy.example.com

コンテナへ必要なパッケージをインストール

以下のパッケージをコンテナ内で利用します。

  • yumでインストールするもの
  • easy_installでインストールするもの
    • supervisor

これらをインストールするために、Dockerfileに以下の様に追加します。

RUN yum update -y
RUN yum install -y openssh-server httpd php php-mbstring mysql-server php-mysql python-setuptools
RUN yum clean all
RUN easy_install supervisor

sshdの設定

次にsshの設定です。*1
コンテナ作成の前に、鍵ペアを作成します。

$ ssh-keygen -f ./id_rsa

id_rsa、id_rsa.pubが作成されるので、id_rsa.pubをコンテナの中の~/.ssh/authorized_keysに入れる事になります。
公開鍵をauthorized_keysへ追加するために、Dockerfileに以下を追加します。

ADD id_rsa.pub /root/id_rsa.pub
RUN mkdir -p /root/.ssh/
RUN cp /root/id_rsa.pub /root/.ssh/authorized_keys
RUN chmod 700 /root/.ssh
RUN chmod 600 /root/.ssh/authorized_keys

~/.ssh
~/.ssh/authorized_keys
パーミッションが不適切だった場合、ログイン出来なくなるので注意が必要です。*2

このままだとログイン出来なかったため、PAMを無効にしています。また/etc/init.d/sshdでsshdを一度起動すると、サーバの鍵の生成が行われます。

RUN sed -i -e '/^UsePAM\s\+yes/d' /etc/ssh/sshd_config
RUN /etc/init.d/sshd start && /etc/init.d/sshd stop

mysql

続いてmysqldの設定です。
sshdと同様に/etc/init.d/mysqldで起動するとデータベース作成を行ってくれます。ただし、このスクリプト内で/etc/sysconfig/networkを参照しているため、ダミーのファイルを作成しています。途中でついでにrootのパスワードも設定しています。

RUN touch /etc/sysconfig/network
RUN /etc/init.d/mysqld start && mysqladmin -u root password 'your_password' && /etc/init.d/mysqld stop

tcp接続が必要な場合は、

RUN /etc/init.d/mysqld start && mysqladmin -u root password 'your_password' && (echo 'grant all privileges on *.* to root@"%" identified by "your_password" with grant option;' | mysql -u root -pyour_password) && /etc/init.d/mysqld stop

の様にしておけばOKです。

supervisor

次にsupervisorの設定です。

supervisor.confはepelの物をインストールした際のファイルを利用しました。*3
sshd、mysqld、httpdを起動するため、supervisor.confに以下の内容を追加します。

[program:httpd]
command=/usr/sbin/httpd -D FOREGROUND

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

[program:mysqld]
command=/usr/bin/mysqld_safe

Dockerfileには上記のsupervisor.confのコピーとログ出力先の/var/log/supervisor/を作成を追加します。

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

EXPOSEとCMD

sshd、httpd、mysqldがそれぞれ22、80、3306ポートを利用。supervisorの起動を指定。

EXPOSE 22 80 3306

CMD ["/usr/bin/supervisord"]

ビルドと起動

Dockerfile、ssh用の鍵ペア、supervisor.confが準備できたらいよいよコンテナのビルドです。tagは適当な名前を指定。Dockerfileを置いてあるディレクトリで以下のコマンドを実行すると、コンテナのビルドが開始されます。

$ docker build -t tag .

コンテナ内で必要なパッケージのインストール等が進みます。
問題なく完了すれば、centos:というイメージが作成されます。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              tag                 555630aa0003        3 hours ago         753.2 MB
<none>              <none>              691908e81641        3 hours ago         794.7 MB
centos              6.4                 539c0211cd76        10 months ago       300.6 MB
centos              latest              539c0211cd76        10 months ago       300.6 MB

コンテナは以下のコマンドで起動できます。

  • pオプションはポートの指定で、コンテナ外:コンテナ内の指定です。
$ docker run -d -p 2345:22 -p 10080:80 -p 13306:3306 centos:tag

コンテナへのログインは

$ ssh -p 2345 -i id_rsa root@localhost

httpdの動作確認は

$ http_proxy= curl http://localhost:10080/

等で行う事ができます。

作成したコンテナはdocker exportで一つのファイルに書き出し、docker importで読み込む事ができます。
たとえば、

$ docker export CONTAINER_ID | gzip > container.tar.gz

で作成したファイルをコピーし、

$ zcat container.tar.gz | docker import - centos:imported

でインポートするとインポート先で直に起動する事が出来ます。
今回作成したコンテナはgzip圧縮した状態で155M程度とそれほど大きくはありません。

まとめ

噂のDockerを触ってみました。慣れるまでは何がどうなっているのか良くわかりませんが、使いこなせる様になると非常に便利だと思います。
例えば、テストデータを入れたコンテナを作成しておくと数秒でEnd to Endのテストが出来るサーバを立ち上げると言った事が可能になります。
また、コンテナをexportすると、boot2dockerだけ準備しておいてもらえればどこでも簡単にデモを行ったりできます。

Dockerfileとsupervisor.confは↓を参照してください。
gist9204349

*1:sshdを起動しておかないと、動作中のコンテナ内の調査が大変です

*2:sshでコンテナ内に入れないため、確認も一苦労です

*3:echo_supervisord_confの結果を編集して利用した方が良いのでしょうが