LoginSignup
167
176

More than 5 years have passed since last update.

Dockerコンテナ内にmysqlサーバを立てる

Last updated at Posted at 2014-05-31

概要

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

参考

167
176
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
167
176