概要
Concourse CIを使ってRailsアプリケーションをデプロイするデモです。
情報が少なく、色々と自分なりに工夫しました。
これがベストプラクティスなのかどうかは分かりませんが、ひとまずこれでやりたいことは実現できました。
環境
- CentOS 7.2
- kernel 4.12.4-1.el7.elrepo.x86_64
- fly 3.3.4
- docker 17.05.0-ce
- docker-compose version 1.15.0
- ruby2.4.1
前提条件
以下の条件を満たすようなConcourse CIを作ります。
1. ビルドキャッシュを使う
bundle installを毎回1からやると時間がかかってしまうので、キャッシュする
2. ブランチによってpipelineを分ける
stagingブランチにマージされたらstaging環境へ、productionブランチにマージされたらproduction環境にデプロイする
3. pipelineは独立させる
pipelineのファイルは、railsアプリケーションのレポジトリに入れるのではなく、独立したレポジトリで管理し、concourse-ciのサーバーに設置する
4. ビルドログの永続化(未実施)
docker-compose down
すると、ビルドの履歴や、登録したpipelineなどがすべて消えてしまう
運用フロー
簡単にですが、運用フローは以下のようになります。
- Rails Application レポジトリのstaging、productionブランチにマージ
- Concourse CIが動く
- Railsのrspecが実行される
- Capistranoが実行されてデプロイ
サーバー構成
vagrantを使って以下の環境を構築します。
参考:Vagrantのインストール、設定手順
それぞれのサーバーには、services
の列に書かれているソースを設置します。
hostname | ipaddr | services |
---|---|---|
concourse-ci | 192.168.33.10 | |
staging | 192.168.33.11 | Rails Application |
production | 192.168.33.12 | Rails Application |
サンプル用ソース
各種アプリケーションのソースは、githubに上げてある以下の4つのレポジトリのものを使用します。
Capistranoは、Concourse CIのdockerコンテナ内で実行するので、ホストOS上には設置しません。
GitHub repository | 用途 | 設置するサーバー |
---|---|---|
concourse-ci | Concourse CI本体 | 192.168.33.10 |
concourse-ci-pipelines | Railsをデプロイするためのpipeline | 192.168.33.10 |
rails-sample | テスト用Rails Application |
|
capistrano-sample | テスト用Capistrano | - |
環境構築手順
concourse-ci(192.168.33.10)の環境構築
カーネルのバージョンアップ
Concourse CIを使うためには、kernelのバージョンは、v3.19以上である必要があります。
uname -r
コマンドで、kernelのバージョンを確認して、バージョンが低い場合はアップデートをしてください。
以下に、kernelをupdateするためのシェルスクリプトを作成しました。
こちらを実行すれば、カーネルがアップデートされます。
CentOS7.2でしか動作検証していません。
https://github.com/Esfahan/kernel-updater
もし、このシェルスクリプトでアップデートできない場合は、以下を参考にしてアップデートしてください。
VagrantのCentOS7のカーネルを更新(yum)
docker-composeのインストール
こちらを参考に、docker-composeをインストールしてください。
docker(docker-engine), docker-composeのインストール
staging(192.168.33.11), production(192.168.33.12)の環境構築
こちらを参考にしてruby2.4.1をインストールしてください。
また、rails-app
という名前のlinuxユーザーを作成してください。
Concourse CIの設置、設定
concourse-ciの設置
ソースの取得
Concourse CI本体のソースを取得します。
$ git clone https://github.com/Esfahan/concourse-ci
webとworkerのためのキーを作成
docker-compose.ymlがある階層で実行します。
$ mkdir -p keys/web keys/worker
$ ssh-keygen -t rsa -f ./keys/web/tsa_host_key -N ''
$ ssh-keygen -t rsa -f ./keys/web/session_signing_key -N ''
$ ssh-keygen -t rsa -f ./keys/worker/worker_key -N ''
$ cp ./keys/worker/worker_key.pub ./keys/web/authorized_worker_keys
$ cp ./keys/web/tsa_host_key.pub ./keys/worker
.envの作成
内容は適宜変更してください。
$ mv .env.example .env
CONCOURSE_BASIC_AUTH_USERNAME=管理画面にログインするためのユーザー名
CONCOURSE_BASIC_AUTH_PASSWORD=管理画面にログインするためのパスワード
CONCOURSE_EXTERNAL_URL=http://192.168.33.10:8080(管理画面のURL:8080)
CONCOURSE_POSTGRES_USER=postgresのユーザー名
CONCOURSE_POSTGRES_PASSWORD=postgresのパスワード
Concourse CIを起動
$ docker-compose up -d --build
以下のURLにアクセスすると、画面が見れるようになっているはずです。
.envでセットしたアカウントでログインしてみてください。
http://192.168.33.10:8080
CLIのインストール
Concourse CIをCLIで実行するためにflyを使います。
以下の記事を参考にしてインストールしてください。
pipelinesの設置
ソースの取得
Railsをデプロイするためのpipelineのソースを取得します。
$ git clone https://github.com/Esfahan/concourse-ci-pipelines
秘密鍵を定数にセット
pipelineでgitを扱うためと、capistranoでデプロイする際に使う秘密鍵を、以下のようにして定数にセットします。
どちらも同一の鍵を使用するので、定義する定数は1つです。
---
github-private-key: |
-----BEGIN RSA PRIVATE KEY-----
**snip**
-----END RSA PRIVATE KEY-----
Concoures CIにログイン
Concoures CIにflyコマンドでログインします。
-t
のあとの名前は、任意のものを付けてください。
$ fly -t concourse-sample login -c http://192.168.33.10:8080
ログイン成功すると、以下のコマンドでターゲットの一覧を確認できます。
$ fly targets
name url team expiry
concourse-sample http://192.168.33.14:8080 main Sat, 30 Sep 2017 07:33:20 UTC
pipelineの書式
長くなるので、別記事にしました。
Concourse CIのpipelineの書き方
こちらのソースの詳細な説明となります。
https://github.com/Esfahan/concourse-ci-pipelines
pipelineの書き方を知りたい場合に参考にしてください。
pipelineをConcourse CIに登録
Concourse CIは、以下の流れでデプロイを実行します。
- pipelineをConcourse CIに登録
- Concourse CIが定期的にレポジトリをチェックし、前回デプロイ時とソースに差分があると自動でデプロイをする
- pause中はデプロイしないが、unpuaseにした時点で差分を検知すればデプロイが始まる(pauseについては後述)
以下のコマンドでpipelineを登録します。
$ fly -t [target name] set-pipeline -p [pipelineの名前] -c concourse-ci-pipelines/rails-sample/pipelines/pipeline.yml -l ~/.concourse/credentials.yml
target name
は、login時に付けた名前、pipelineの名前
は、何でもよいのですが、アプリケーションの名前を付けるとわかりやすいと思います。今回は、以下の内容で登録をします。
$ fly -t concourse-sample set-pipeline -p rails-sample -c concourse-ci-pipelines/rails-sample/pipelines/pipeline.yml -l ~/.concourse/credentials.yml
apply configuration? [yN]: y
pipeline created!
you can view your pipeline here: http://192.168.33.10:8080/teams/main/pipelines/rails-sample
the pipeline is currently paused. to unpause, either:
- run the unpause-pipeline command
- click play next to the pipeline in the web ui
pipelineの図を確認
登録が完了すると、web画面で以下のようなpipelineの図が見れるようになっているはずです。
http://192.168.33.10:8080
黒い四角はgitレポジトリ、灰色はdockerコンテナで、
実線は、そのgitレポジトリのソースに変更があったらCIが稼働するという意味で、点線は変更があってもCI稼働のトリガーとならないものです。
デプロイ待機状態にする
このままではまだデプロイされません。
web画面の左メニューを見ると、pipelineの名前
の横に、再生ボタンがあると思います。
このボタンをクリックするか、以下のコマンドを実行することで、デプロイ待機状態となり、
gitのソースに差分があることを検知すると、自動でデプロイが実行されるようになります。
コマンドでunpauseしてみます。
$ fly -t concourse-sample unpause-pipeline -p rails-sample
すると、以下のように、rails-job-staging
とrails-job-production
が光りだし、デプロイが始まります。
capistrano-sample
がオレンジ色になっているのは、エラーが起きているからです。
存在しないブランチ名を定義してしまっていたことが原因でした、気にしないでください。
このように、エラーが起きた場合はオレンジ色になります。
実行内容を確認
rails-job-stagingをクリックすると、以下のように、実行内容を確認できます。
以下の画像は、実行が正常終了したあとのものですが、実行中は黄色、エラー終了の場合はオレンジになります。
全て正常終了すると、緑になります。
これでデプロイ完了です!
コマンドでも実行させることもできます。
$ fly -t concourse-sample trigger-job -j rails-sample/rails-job-staging
各種ステータス
TOPページの左下にあるように、各種ステータスの説明があります。
手動実行
実行内容詳細の画面の右上の+
ボタンで、手動実行させることも可能です。
ビルドキャッシュについて
前提条件のところに書いたとおり、ビルドキャッシュを有効にしています。
その証拠に、bundle install
が実行される、rails-job-staging
とrails-job-production
ともに、1回目より2回目以降のほうが、実行時間が短くなっています。
durationが、初回は2分51秒だったのが、2回目以降は、9秒に短縮されています。
ただし、キャッシュは、キャッシュ用コンテナで管理されているので、docker-compose down
をすると、キャッシュクリアされます。
同時実行数
pipelineに、max_in_flight
というものを定義すると、同時実行数がセットできるみたいです。
デフォルトは1
みたいです。
詳しくは以下で。
https://concourse.ci/configuring-jobs.html#max_in_flight
以上