Edited at

CircleCI経由でRailsアプリをデプロイ

More than 3 years have passed since last update.

最近CircleCIもprivate repoのビルドが無料になった。(1コンテナまで)

せっかくなので使ってみようということで、

Railsアプリのビルド実行に使うサービスをwerckerから乗り換えてみた。その設定などのメモ。

Continuous Integration and Deployment on CircleCI just got better: now it’s free. | The Circle Blog


設定ファイル

他のCIサービスと同じく、基本的にRailsプロジェクトのルートディレクトリに置いたyamlファイル(circle.yml)に記述していく。

設定については、ドキュメント見れば詳しく書いている。

Configuring CircleCI - CircleCI

凝ったことをする必要がなければ、そんなに設定をいっぱい書かずともビルドとデプロイができる印象。werckerより楽だった。

今のところ、こんな感じの設定にしている。


circle.yml

machine:

timezone:
Asia/Tokyo
ruby:
version: 2.1.3

dependencies:
pre:
- sudo pip install awscli

deployment:
staging:
branch: deploy-staging
commands:
- sh script/deploy-staging.sh:
timeout: 1500
production:
branch: deploy-production
commands:
- sh script/deploy-production.sh:
timeout: 1500


CircleCIでのビルドは以下の6つののフェーズに分かれており、それを上記の設定ファイルに書いていくようだ。


  • machine

  • checkout

  • dependencies

  • database

  • test

  • deployment

また、以下のキーワードを書いておくと、

各フェーズでCircleCIが実行してくれるコマンドをオーバーライドしたり、前後に他の作業を差し込んだりすることができる。


  • pre

  • override

  • post

さらに、各コマンドにはオプションのようなものを付けて実行することが可能。


  • timeout

  • environment

など。(今回はtimeoutのみ利用)


各フェーズの超ざっくりした説明


machine

ビルドに使うVMのセッティング。

VMのタイムゾーンの指定と、利用するRubyのバージョンだけ指定。


checkout

コードをcheckoutするときの設定。基本的にはデフォルトのままで良さげなので、今回はノータッチ。


dependencies

VMにデフォルトで入ってるbundlerじゃなくて、最新版を使いたい!とかいうときはここで指定するとヨサソウ。

何も指定しないとbundle installのみが実行される。

VMにインストールされているawscliのバージョンがどうやら古い。

後述するが、デプロイ時に新しいバージョンのものを利用するのでpipでインストールしている。


database

データベースまわりの設定。

デフォルトでは、テスト環境用のconfig/database.ymlを生成し、

bundle exec rake db:create db:schema:load --traceを実行してくれる。

ノータッチ。


test

テスト実行部分。

デフォルトではbundle exec rspec --color --require spec_helper spec --format progressの実行。

そのまま利用。


deployment

デプロイ実行部分。

staging, productionなどの環境を指定し、どのブランチにgit pushがされるとデプロイを実行するのか書く。

(上記の例なら、deploy-productionブランチにpushされると、production環境へのデプロイが行われる)

デプロイには、deploy-production.sh(deploy-staging.sh)というシェルスクリプトを利用している。

このときrake assets:precompileなどちょっと時間がかかる行程があるので、timeoutを1500sにしている。

※timeoutのデフォルト値は180sで、出力が3分間何も無いと、プロセスが終了されてしまう


デプロイのスクリプト

CircleCIのdeploymentフェーズで使う、デプロイ用のスクリプト。


script/deploy-production.sh

#!/bin/sh

set -ex

export AWS_DEFAULT_REGION="ap-northeast-1"

MYSECURITYGROUP=<デプロイ先のセキュリティグループのID>
MYIP=`curl -s ifconfig.me`

aws ec2 authorize-security-group-ingress --group-id $MYSECURITYGROUP --protocol tcp --port 22 --cidr $MYIP/32

bundle exec cap production deploy

aws ec2 revoke-security-group-ingress --group-id $MYSECURITYGROUP --protocol tcp --port 22 --cidr $MYIP/32


以下のような流れ。


  • どこかのプロセスが失敗した時点でビルド全体が失敗するようsetコマンド実行


  • awsコマンドを使いたいので、環境変数指定


    • AWSのキーペアは、CircleCI側に登録しておく



  • ビルドしているコンテナのIPアドレスを取得(MYIP

  • SSHログインできるよう、デプロイ先のサーバのセキュリティグループにコンテナのIPアドレスを追加


    • 秘密鍵をCircleCIに登録しておく(渡すのが嫌な人は別の手段が必要ですね...)

    • このとき、元々インストールされてるawscliだとバージョンが古くてコケるぽい



  • デプロイ実行

  • 先ほど追加したIPアドレスをセキュリティグループから削除


通知

Webの設定画面から、チャットアプリと連携できる。SlackやHipchat, Campfireなどは普通に対応している。

ビルドが終わると、こんな通知が来るようになります。

スクリーンショット 2014-11-27 19.05.41.png


おわり

(難しいことを全くしていないので当たり前かもしれませんが、)特に躓くことなくデプロイまでできました。コンテナにSSHログインできる機能もあるみたいだし便利ですね。

...werckerに出戻りすることは今のところ全く無さそうです。