hidemium's blog

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

DockerでアプリケーションとMySQLをコンテナ化してRedmineを構築する

Dockerの公式リポジトリsameersbn/redmineというRedmineのイメージがあったので試してみました。

このイメージの面白いところは、アプリケーションだけでなくデータベースもコンテナにし、さらにデータファイルをコンテナから分離してるところです。

構成

Ubuntu 12.04: Docker 0.10.0、Redmine 2.5.1、MySQL 5.6
※上記のサーバはVMware ESXi 5.1上で動作しています。

インストール

MySQL

まずは、以下のコマンドでMySQLのイメージをダウンロードします。

$ sudo docker pull sameersbn/mysql:latest

次にMySQLのデータディレクトリをホスト側で保存するため、ホスト側でディレクトリを作成します。

$ sudo mkdir -p /opt/mysql/data

docker runコマンドでMySQLのコンテナを起動します。
「-v」オプションを使い、コンテナ内のファイルを上記で作成したディレクトリに保存するようにしています。

$ sudo docker run --name mysql -d -v /opt/mysql/data:/var/lib/mysql sameersbn/mysql:latest

以下のコマンドで、MySQLのコンテナにログインします。
「docker inspect mysql~」は、MySQLのコンテナのIPアドレスを取得しています。

$ sudo mysql -uroot -h $(sudo docker inspect mysql | grep IPAddres | awk -F'"' '{print $4}')

MySQLのコンテナにログイン後、「redmine」ユーザと「redmine_production」データベースを作成します。
「172.17.%.%」と指定することで、コンテナ間での接続ができるようにしています。

CREATE USER 'redmine'@'172.17.%.%' IDENTIFIED BY 'redmine';
CREATE DATABASE IF NOT EXISTS `redmine_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
GRANT SELECT, LOCK TABLES, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `redmine_production`.* TO 'redmine'@'172.17.%.%';
FLUSH PRIVILEGES;

Redmine

以下のコマンドでRedmineのイメージをダウンロードします。

$ sudo docker pull sameersbn/redmine:latest

次にRedmineに登録したファイルをホスト側で保存するため、ホスト側でディレクトリを作成します。

$ sudo mkdir -pv /opt/redmine/files

以下のコマンドでRedmineの初期設定とデータベースのテーブルを作成します。
「--rm」オプションはコンテナ起動後にコンテナを削除する設定です。
「--link」オプションはコンテナ間の連携をする設定で、「連携したいコンテナ名:エイリアス名」を指定します。
「-e」オプションは環境変数を指定するための設定です。
「-v」オプションはコンテナ内のファイルをホスト側に保存するための設定です。

$ sudo docker run --name redmine2.5.1_link -i -t --rm --link mysql:mysql -e "DB_USER=redmine" -e "DB_PASS=redmine" -e "DB_NAME=redmine_production" -v /opt/redmine/files:/redmine/files sameersbn/redmine:latest app:db:migrate
User: root Password: xxxxxxxxx
sshd: started
memcached: stopped
memcached: updated process group
memcached: started
Your Gemfile lists the gem fastercsv (~> 1.5.0) more than once.
You should probably keep only one of them.
While it's not a problem now, it could cause errors if you change the version of just one of them later.
Your Gemfile lists the gem yard (>= 0) more than once.
You should probably keep only one of them.
While it's not a problem now, it could cause errors if you change the version of just one of them later.
redmine_production already exists
Your Gemfile lists the gem fastercsv (~> 1.5.0) more than once.
You should probably keep only one of them.
While it's not a problem now, it could cause errors if you change the version of just one of them later.
Your Gemfile lists the gem yard (>= 0) more than once.
You should probably keep only one of them.
While it's not a problem now, it could cause errors if you change the version of just one of them later.
==  Setup: migrating ==========================================================
-- create_table("attachments", {:force=>true})
   -> 0.0240s
-- create_table("auth_sources", {:force=>true})
   -> 0.0076s
-- create_table("custom_fields", {:force=>true})
   -> 0.0074s
-- create_table("custom_fields_projects", {:id=>false, :force=>true})
:

以下のコマンドで、Redmineを起動します。

$ sudo docker run --name redmine2.5.1_link -d -p 80 --link mysql:mysql -e "DB_USER=redmine" -e "DB_PASS=redmine" -e "DB_NAME=redmine_production" -v /opt/redmine/files:/redmine/files sameersbn/redmine:latest

コンテナの状態を確認すると、RedmineMySQLのコンテナが起動してるのが分かります。
80番ポートにポートフォワードするポートは、PORTSの「0.0.0.0:49221->80/tcp 」から「49221」であることが分かります。

$ sudo docker ps -a
CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                    PORTS                                          NAMES
f46be945ba2d        sameersbn/redmine:latest   /redmine/init app:st   5 hours ago         Up 5 hours                22/tcp, 0.0.0.0:49221->80/tcp                  redmine2.5.1_link
b9f0ba33ab50        sameersbn/mysql:latest     /app/init app:start    5 hours ago         Up 5 hours                22/tcp, 3306/tcp                               mysql,redmine2.5.1_link/mysql

ブラウザから、「http://localhost:49221」にアクセスし、Redmineのログイン画面が表示されることを確認します。
ただし、アクセス直後はInternal Error 500というエラーが出る場合があり、何度かリロードすると正しく表示されるようになりました。

おわりに

Immutable Infrastructureの実現には、Stateless ServerはDockerを利用し、Stateful Serverは今まで通りDBサーバを利用して運用するイメージを持っていました。
しかし、Dockerはファイルを分離してホスト側で保持することができ、DBサーバもコンテナで起動することができるため、Dockerの利用用途としてStateful Serverも対象になる可能性があると感じました。
もし、DBサーバもコンテナとして利用できれば、Blue-Green Deploymentといった手法として、以下のようにDBサーバごと切り替えられるかもしれません。
※DBサーバを物理的にもう一台用意するイメージかもしれませんが。。

・Blue: APコンテナ(現行) - DBコンテナ(現行)
・Green: APコンテナ(新規) - DBコンテナ(新規)

今後、DBサーバをコンテナ化した場合に、どのような問題が発生するか試してみたいと思います。(あまり情報がないため、知っている人がいればぜひ教えてください。)