概要
Dockerコンテナ内にmysqlサーバを立てます。
mysqlアカウントを作成したり、mysqlサーバを外部に公開することも行います。
動作確認を行った環境は、ホストOS, コンテナOSともにCentOSです。
そもそもDockerとは
仮想環境構築に docker を使う - apatheia.info を読んでください!
Dockerfile
さっそくですが、以下が Dockerfile です。
コンテナイメージを作成するために必要なファイルです。
# DOCKER-VERSION 0.3.4
FROM centos:6.4
# ここは自由に変えてください
MAINTAINER Taro Tanaka
# パッケージインストール
RUN yum install -y mysql mysql-server
# mysqlサーバのセットアップ
RUN echo "NETWORKING=yes" > /etc/sysconfig/network
ADD ./setup.sql
RUN /usr/bin/mysqld_safe & \
sleep 10s && \
cat setup.sql | mysql
# 外部からmysqlサーバにアクセスできるように
RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnf
# ポート番号 3306 を外部に公開
EXPOSE 3306
CMD ["/usr/bin/mysqld_safe"]
構文解説
Dockerfile 内で書かれている Instruction について軽く解説します。
- FROM <image>
- コンテナで利用するOSイメージです
- この例では「centos:6.4」
- 「centos』とだけ書くと、最新版を利用するようです
- MAINTEINER <name>
- Dockerfile の作成者
- RUN <コマンド>
- コンテナ環境でコマンドを実行させます
- ADD <src> <dest>
- ホスト環境のファイルをコンテナ環境へコピーします
- EXPOSE <port>
- コンテナ環境の外から参照させたいポート番号を指定します
- mysqlサーバの場合は 3306. HTTPサーバだと通常 80 を指定します
- CMD
- CMD はDockerfileに1つしか記述できません。
- 引数なしでコンテナを起動したときの、挙動を書きます
- コンテナ起動のセクションでまた触れます
また、docker でキャッシュを活用するためには、あまり変わらないInstructionをDockerfileの上の方に記述するのがいいそうです。
MySQLセットアップ部分
MySQL固有の部分に関する部分を抜粋します。
RUN echo "NETWORKING=yes" > /etc/sysconfig/network
ADD ./setup.sql ./setup.sql
RUN /usr/bin/mysqld_safe & \
sleep 10s && \
cat setup.sql | mysql
まず1行目の /etc/sysconfig/network
を生成している部分についてです。
この行がないとCentOSをコンテナOSとする場合に、mysqlが起動できないので、追加しています。
2行目はSQLスクリプトをコンテナで利用できるようにコピーしているだけです。
3行目は「mysqlサーバを起動させて、起動が完了するであろう10秒後に、セットアップ用のSQLを流し込む」という処理です。
setup.sql
にアカウント追加やデータベース作成、テーブル作成など処理を書いていて、それを実行しています
ここでの処理を見て、「1行にごちゃごちゃ詰め込むのではなく、3行に分けてRUNを書けばいいのでは?」と思われるかもしれません。
実は、ここが今回の最大のポイントです。というのも、3行に分けてRUNを書くと、setup.sqlでの処理は正しく動きません。
なぜかというと、RUNが別の行にまたぐと、ファイルシステム上での変化は記憶されるのですが、メモリやプロセスの状態変化は保持されないからです。
そのため、アカウント作成、テーブル作成といった処理を行うためには、mysqlサーバが起動している状態である必要ので、1行のRUNで処理を完結させているというわけです。
MySQLサーバをコンテナ外部からもアクセスさせる
RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnf
デフォルトだとmysqlサーバは localhost からの接続しか許さないようになっているので、my.cnfを書き換えてあげます。
このsedコマンドでは、my.cnfの 127.0.0.1 となっている行を 0.0.0.0 に置換しています。
コンテナイメージの作成
Dockerfile の編集が完了したら、コンテナイメージを作成しましょう。
コンテナにタグをつけておくと、参照しやすいです(-t オプション).
また、タグ名は <自分のユーザ名>/<コンテナ名> とするのが良い習慣だそうです。
$ sudo docker build -t gologo13/mysql .
コンテナ起動
コンテナイメージの作成に成功すれば、次はコンテナの起動です。
以下のように引数なしでdocker run
を実行すれば、Dockerfileに書いた CMDの内容/usr/bin/mysqld_safe
が実行されます。
docker run することで、mysqlサーバのデーモンプロセスの起動完了です!
$ sudo docker run -i -p 3306:3306 -t gologo13/mysql
また、コンテナ内でコマンドを実行したい場合は、シェルを立ち上げることもできます。この時、CMD で記述した内容は実行されません。
$ sudo docker run -i -p 3306:3306 -t gologo13/mysql /bin/bash
MySQLサーバへのアクセス
最後に、dockerコンテナ内でmysqlサーバにアクセスします。
以下の様なスクリプトを作っておくと、アクセスが楽になります。
処理的には、コンテナIDを取得して、そのコンテナの詳細情報からIPアドレスを取得しています。
$ cat mysql_client.sh
#!/bin/sh
# docker build 時に指定したタグ名
TAG="gologo/mysql"
CONTAINER_ID=$(docker ps | grep $TAG | awk '{print $1}')
IP=$(docker inspect $CONTAINER_ID | python -c 'import json,sys;obj=json.load(sys.stdin);print obj[0]["NetworkSettings"]["IPAddress"]')
# アカウントとパスワードは適宜変更してください
mysql -u admin -ppassword -h $IP
あとは実行すればおしまいです。
$ chmod u+x mysql_client.sh
$ sudo mysql_client.sh