Amazon EC2 Container Service (ECS) と CircleCI を活用した Docker ベースなコーポレートサイト
目次
コーポレートサイトを一部リニューアル
今月のはじめに、弊社のコーポレートサイトを一部リニューアルしている。
内容だけではなく、バックエンドのシステム側も AWS OpsWorks を使って構築した環境へデプロイしていたものから、 Amazon EC2 Container Service (ECS) を使った Docker
ベースのものへと変更している。
弊社では、これまで開発環境では Docker
を使っていたが、本番環境での Docker
運用はしていなかった。
そろそろ本番環境でも Docker
を使った環境に移行したいと思い、 ECS
環境への移行を行った。
今回は、その移行の際のポイントをまとめてみたいと思う。
Docker Hub
- 前述のとおり、開発では
Docker
を使っており、Docker Hub を使っていたので、そのままECS
でも Docker Hub を使っている(今回は Amazon EC2 Container Registry (ECR) は使わない) - Docker Hub にはあらかじめ
Ruby on Rails
で稼働している弊社コーポレートサイトが一通り動作する、ビルド済みのベースとなるイメージを置く - 開発時や、
CircleCI
でテストを実行する際は、そのベースイメージをPull
してアプリケーションのソースを追加、テストが通ったら、アセットファイル群をプリコンパイルして、デプロイ。そうすることで、0からビルドするよりは時間の短縮が出来る AWS ECR
ではなくて、Docker Hub を使う場合、ECS
対応AMI
の場合は下記のように/etc/ecs/ecs.config
に追加する必要がある
ECS_ENGINE_AUTH_TYPE=docker
ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"username":"ユーザー名","password":"パスワード","email":"メールアドレス"}}
-
これを、
EC2
インスタンス起動時に追加できるように、EC2
のユーザーデータに設定
#!/bin/bash
echo "ECS_ENGINE_AUTH_TYPE=docker" >> /etc/ecs/ecs.config
echo 'ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"username":"ユーザー名","password":"パスワード","email":"メールアドレス"}}' >> /etc/ecs/ecs.config
CircleCI
CircleCI
のバージョンは、ベータ中の2.0
の検証がまだ出来ていないので、1.0
を使用2.0
ではdocker-compose
が使えたり、かなり便利になっているようなので、検証が出来次第そちらに移行したいと考えている- 【参考URL】Using docker-compose - CircleCI
Docker コンテナのビルド、キャッシュ
- ビルドしたコンテナは、
tar
ファイルとして保持しておく - ビルド実行時に、
tar
ファイルを読み込んで、ビルドを高速化 tar
ファイルが配置されている~/docker
ディレクトリはキャッシュする設定を追加
dependencies:
cache_directories:
- "~/docker"
override:
- if [[ -e ~/docker/image.tar ]]; then docker load -i ~/docker/image.tar; fi
- docker build --rm=false -t app .
- mkdir -p ~/docker; docker save app > ~/docker/image.tar
テストで使う MySQL
は Docker
コンテナを使わない
CircleCI
環境でデフォルトで起動するMySQL
を使って、テストを行う(DB
のコンテナは作成しない)- アプリケーションのコンテナから、ホスト側で稼働している
MySQL
に接続するため、接続用のユーザー作成を行う
database:
override:
- mysql -uroot mysql < scripts/create_rails_user.sql
scripts/create_rails_user.sql
は下記のような内容。
GRANT ALL PRIVILEGES ON *.* TO 'rails'@'%' identified by "rails";
FLUSH PRIVILEGES;
- アプリケーションのコンテナから、ホスト側で稼働している
MySQL
に接続するため、外部接続設定(bind-address
の行をコメントアウト)を変更
machine:
pre:
- sudo sed -Ei 's/^(bind-address|log)/#&/' /etc/mysql/mysql.conf.d/mysqld.cnf
- テストは、
docker run
で、下記のように実行
test:
override:
- docker run --add-host db:$(ip addr show docker0 | grep "inet" | awk '{print $2}' | cut -d/ -f1) -e RAILS_DATABASE_HOST=db app bundle exec rspec spec
ECS
ログは標準出力するように
- ログの出力を標準出力に変更して、
CloudWatch
で確認できるように
例えば unicorn
の設定ファイル config/unicorn.rb
のログファイルの設定箇所をコメントアウトして、標準出力にすることで、 ECS
で設定している CloudWatch
のロググループにログストリームを送信できるようになる。
# log
# stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
# stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
silinternational/ecs-deploy を使ってデプロイ
- silinternational/ecs-deploy を使うと、簡単に
Blue Green Deployment
が出来てしまうのでこれを利用 CircleCI
からは、下記のように実行している
- $(aws ecr get-login --region ap-northeast-1)
- docker tag app mmmcorp/corporate_web:$CIRCLE_SHA1
- docker push mmmcorp/corporate_web:$CIRCLE_SHA1
- ./scripts/ecs-deploy --timeout $ECS_TIMEOUT -c $PRD_ECS_CLUSTER -n $PRD_ECS_SERVICE -i mmmcorp/corporate_web:$CIRCLE_SHA1
Datadog
- 監視には、
Docker
の監視が出来るDatadog
を使用 - 【参考URL】Datadog-AWS ECS Integration
まとめ
CircleCI
で Docker
コンテナをビルド、テスト実行して、 ECS
へデプロイする際のポイントをざっくりとまとめてみた。
同じような環境を構築しようとしている方に、何か少しでも役に立てれば幸いである。CircleCI 2.0
を使うことになった際には、また設定等の変更が必要になるので、そのときにはまた改めてブログにまとめられるといいかな、と思っている。
-
前の記事
新人プログラマの時に知っておきたかった「ハマったときの考え方とフローチャート」 2017.04.24
-
次の記事
新規事業など継続的開発が見込まれるプロジェクトでのJIRA運用 2017.04.30