Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
Jenkins入門【2.0対応】 - オープンソースCIツール(3)

Jenkins入門【2.0対応】 - オープンソースCIツール(3)

Jenkinsでアプリケーションをデプロイしてみよう

2016年6月22日 改訂 (初版: 2014/01/17)

継続的インテグレーションの手順のうち、デプロイに焦点を当てて、テストの実行から、GitによるHeroku環境へのデプロイまでを自動化する方法を解説。Mac向けのGrowlを使って実行結果を通知する方法も説明。

山本 和久(Hatena::Diary
  • このエントリーをはてなブックマークに追加

 連載第1回「Jenkinsを使ってみよう」ではMac(OS X)/Linux/Windowsへのインストール方法を、第2回「Jenkinsでテストを実行してみよう」ではユニットテストおよびインテグレーションテストを作成し、Jenkinsから実行する手法を解説した。ここまで読んでいただいた読者の皆さんもJenkinsをインストールして自分なりの使い方を模索していることと思う。

 さて、連載第1回で「継続的インテグレーションとは次のような手順の繰り返しだ」と説明したのを覚えているだろうか?

  1. プログラミング
  2. テストの実行
  3. リファクタリング
  4. デプロイ

 今回は4番目の「デプロイ」に焦点を合わせ、Heroku(読み方「ヘロク」)にデプロイする方法を説明する。Herokuには無償枠が用意されており、取りあえず本稿の手順を試すぐらいの利用量ではお金を掛けなくて済むので、ぜひ本稿の手順を実施してみてほしい。

ビルドパイプラインとは

 ビルドパイプラインとは、複数のジョブを接続して、1つの大きなジョブとしたものだ。ビルドパイプラインを活用することで、時間がかかる処理を細分化し、開発者に対して早い段階でフィードバックを行える。例えば次の図は、ビルドパイプライン(=ユニットテストインテグレーションテストデプロイというジョブがある)の中のインテグレーションテストで失敗した場合に、開発者(=この図では「ユーザー」)にそれを通知する場合の流れを示している。

図1 インテグレーションテストで失敗した場合、素早く開発者に通知する

通知の設定

 ビルドパイプラインを構築する前に、ユーザーへの通知を設定しておこう。

 Macユーザーであれば「Growl」の利用をお勧めする(WindowsとLinuxでは全く同じ手順とならないので割愛する)。GrowlはMacで古くから利用されている通知ツールである。対応アプリケーションも多いので、これを機にインストールしておこう。

Growlのインストール

 Growlは、(次の画面に示すように)Mac App Storeからインストールできる。

図2 App StoreでGrowlを検索したところ

 インストールしたらOS Xの[アプリケーション]からさっそく起動してみよう。初回起動時は説明が表示されるが、以下に示すように、基本的にはボタンを押していくだけでOKだ。最後の[ログイン時に Growl を開始]ボタンを押し忘れないように注意すること。

図3 Growlのインストールの流れ
Growlのインストールの流れ(1)
Growlのインストールの流れ(2)
図3 Growlのインストールの流れ

Growlの設定

 Growlのインストールが完了したら設定を行おう。

 OS Xのメニューバーの右上に表示されているGrowlのアイコンから環境設定を開く(図4)。

図4 [Growlの環境設定を開く]を実行
図4 [Growlの環境設定を開く]を実行

 次に、Growl環境設定の[ネットワーク]の中にあるパスワードを設定しよう(図5参照。パスワードの入力を可能にするには、[外部からの通知を受け付ける]チェックボックスにチェックを入れる)。

図5 任意のパスワードを設定する
図5 任意のパスワードを設定する

Growl Pluginのインストール

 Growlの設定が完了したら、図6に示すように、Jenkinsに「Growl Plugin」をインストールしよう(プラグインのインストール方法は第2回で解説しているので、そちらを参照)。

図6 「Growl Plugin」をインストールしているところ

Growl Pluginの設定

 [Jenkinsの管理]-[システムの設定]からGrowlの共通設定を行う(図7)。

図7 先ほどGrowlに設定したパスワードを[Global Growl Settings]の[Password]欄に入力して[保存]する
図7 先ほどGrowlに設定したパスワードを[Global Growl Settings]の[Password]欄に入力して[保存]する

 次に(第2回で作成したcircleプロジェクトの)[設定]から[ビルド後の処理の追加]をクリックし、「Growl」を選択し、次の画面のように[IP Address]欄に今回は「localhost」を指定する。最後に[保存]ボタンをクリックする。

図8 通知先としてlocalhostを指定しているところ

 ちなみに「,」(カンマ)で区切って複数のアドレスを指定することもできる。プロジェクトメンバーのアドレスを入力しておけばビルドの状況をチームで把握できるだろう。

Growlへの通知

 さて、準備ができたらcircleプロジェクトをビルドしてみよう。無事テストが完了すると、次のような通知が表示されるはずだ。

図9 テスト成功時の通知例
図9 テスト成功時の通知例

注意:うまく通知されない場合はGrowlの環境設定でアプリケーションがオンになっているかを確認してほしい(次の画面)。
図9 テスト成功時の通知例(うまく通知されない場合)

さまざまな通知方法

 Jenkinsでは、他にもさまざまな通知を行うことができる。

メール

 標準で利用できる通知方法。利用するには、[Jenkinsの管理]-[システムの設定]で、[E-mail 通知]の[SMTPサーバー]を指定しよう。

Chrome拡張

 WebブラウザーでChromeを利用しているユーザーは、「Jenkins Notifier for Chrome」を利用できる。Jenkinsの「Websocket Plugin」と組み合わせれば、Growlと同様に素早く通知を受け取れる。

Webサービス

 最近ではJenkinsと連携できるWebサービスも登場してきている。「idobata」というグループチャットツールはJenkinsとの連携が可能だ。開発チームで使っているチャットにJenkins実行結果が表示されるので、ビルドの状況を共有しやすい。

 これを利用するには、Jenkinsに「Notification Plugin」をインストールして、idobataの[ROOM SETTING]-[Hooks]タブ-[+New hook]-[Jenkins]で表示される説明画面(英語、図10)に従って設定を行おう。

図10 idobataのJenkins用hookのセットアップ説明画面を表示しているところ

この画面に表示されている[Format]/[Protocol]/[URL]の値を、Jenkinsの[Job Notifications]設定に指定する。

Herokuへのデプロイの設定

 テストが完了したら本番環境にデプロイしてみよう。今回はRuby on Railsの本番実行環境として広く利用されている「Heroku」にデプロイする。

アカウントの作成

 Herokuのアカウントを取得していない場合は、以下の手順を参考に、まずhttps://www.heroku.comにアクセスし、アカウントの作成を行おう。

図11 https://www.heroku.comにアクセスしたところ

 [Sign up]ボタンをクリックして、次の画面のように登録フォームを入力する。

図12 メールアドレスの登録

 入力したメールアドレスに本登録用アドレスが送られるはずだ。そのアドレスをクリックしてパスワードの設定を行おう(図13)。

図13 パスワードの設定

 無事、パスワード設定が完了したら、Herokuを利用するためのコマンド群である「Heroku toolbelt」をインストールする。

 今までの連載を読んできたMacユーザーであれば、すでにHomebrewがセットアップされているはずだ。その場合、

「Heroku toolbelt」は次のコマンドでインストールできる。

Bash
$ brew update
$ brew install heroku-toolbelt
リスト1 Heroku toolbeltをインストールするためのコマンド

 次にHerokuへのログインを行う。これにはMacのターミナルに下記のコマンドを入力すればよい。

Bash
$ heroku login
Enter your Heroku credentials.
Email: foo@example.com
Password (typing will be hidden):
Could not find an existing public key. # 公開鍵が作成されていない場合のみ
Would you like to generate one? [Yn] Y
Generating new SSH public key. Uploading SSH public key /Users/kazuhisa/.ssh/id_rsa.pub... done 
Authentication successful.
リスト2 herokuにログインするためのコマンド実行例

デプロイ

 Herokuへのデプロイを行うに当たり、プロジェクトを若干修正しよう(リスト3)。

Gemfile
source 'https://rubygems.org'

……中略……
# gem 'sqlite3' コメントアウトする
……中略……

group :production do
  gem 'pg' # HerokuではPostgreSQLを利用するため必要
  gem 'rails_12factor' # HerokuでRailsを動作させるための細かな調整を行ってくれる
end

group :development, :test do
  gem 'byebug'
  gem 'rspec-rails'
  gem 'capybara'
  gem 'turnip'
  gem 'sqlite3' #追記する
end
リスト3 Gemfileに追記したところ

 Gemfileの修正が終わったら、今までと同様にbundle installコマンドでGemfile.lockファイルを更新する。

 また、Herokuとは直接関係ないが、プロジェクトのRoot(=デフォルトで呼び出されるコントローラー)を指定しておこう(リスト4)。

Ruby
Circle::Application.routes.draw do
……中略……
# You can have the root of your site routed with "root"
  root 'users#index' # デフォルトでusersコントローラーを呼び出すように変更

……中略……

end
リスト4 rootを修正したところ(config/routes.rb)

 ここまでできたら、下記のコマンドをターミナルで実行して、一気にHerokuにデプロイしてしまおう。

Bash
$ git add .
$ git commit -m 'preparation deploy'
$ heroku create # Heroku上にアプリケーションをデプロイする場所を準備する
$ git push heroku master # Herokuへのデプロイを行う
$ heroku rake db:migrate # DBのテーブルを作成する
$ heroku open # Webブラウザーでアプリケーションを開く
リスト5 Herokuへのデプロイ手順

 正しくデプロイされていればWebブラウザーでアプリケーションが表示されるはずだ(図14)。

図14 アプリケーションの表示(URLはユーザーごとに異なるので注意)
図14 アプリケーションの表示(URLはユーザーごとに異なるので注意)

ビルドパイプラインの構築

 いよいよ本題であるビルドパイプラインの構築に取り掛かろう。ここでは次の3つのジョブを作成する。

  • ユニットテスト
  • インテグレーションテスト
  • デプロイ

 その前にパイプラインを構築する上で注意するポイントを説明しておく。

未テストのプロジェクトがデプロイされてしまう可能性

 Jenkinsの各ジョブは、ジョブ別の作業領域で独立して実行される。例えば筆者の環境であれば作業領域は次のディレクトリに存在している。

  /Users/kazuhisa/.jenkins/jobs/circle/workspace

 ジョブの実行時には必ずGitのリポジトリから最新のソースを取得するため、次の図のようにインテグレーションテストが行われている間に別のコミットが行われてしまうと、まだテストが完了していないプロジェクトをデプロイしてしまう可能性が出てくる。

図15 インテグレーションテストが行われている間に別のコミットが行われた場合

 これを防止するために、上位のジョブのパラメーターを下位のジョブに引き継ぐための「Parameterized Trigger」というプラグインが存在している。これを[Jenkinsの管理]-[プラグインの管理]からインストールしておこう(図16を参照)。

図16 プラグインをインストールしているところ

ジョブの設定

 次の3つのジョブを作成する。

  • circle_unit_test
  • circle_integration_test
  • circle_deploy

 それぞれの設定内容は、以下のキャプチャ画像を参考にしてほしい。

circle_unit_test
図17 circle_unit_test

1Repository URL

 監視するGitリポジトリを指定する。

2スケジュール

 次のように5分おきに監視するように指定する。

Jenkins設定
H/5 * * * *
リスト6 5分おきに監視

3シェルスクリプト

 「_spec.rb」で終わる名前のファイルのみ、テスト対象となるように設定する(次のコード)。

Jenkins設定
bundle install
bundle exec rake db:migrate
bundle exec rake db:test:load
bundle exec rspec spec/*/*_spec.rb
リスト7 特定のファイル名のみをテスト対象に設定

4Only Growl on Failure or Recovery?

 Growlのオプション設定を行う。「Yes」に設定するとテストが失敗、もしくは失敗した状態から成功した場合のみ通知を行う。ここでは「Yes」を設定する。

5Project to build

 「Trigger parameterized Plugin」の設定を行う。次に実行されるプロジェクトの名前の「circle_integration_test」を設定する。

6Pass-through Git Commit that was built

 [Add Parameters]ボタンを押して追加する。「GitのコミットIDを、次のテストに引き継ぐ」という意味。

circle_integration_test
図18 circle_integration_test

1シェルスクリプト

 「.feature」で終わる名前のファイルのみテスト対象となるように設定する(リスト8)。

Jenkins設定
bundle install
bundle exec rake db:migrate
bundle exec rake db:test:load
bundle exec rspec spec/*/*.feature
リスト8 特定のファイル名のみテスト対象に設定

2Only Growl on Failure or Recovery?

 Growlのオプション設定を行う。ここもユニットテストと同じく「Yes」を設定する。

3Project to build

 次に実行されるプロジェクト名「circle_deploy」を設定する。

circle_deploy
図19 circle_deploy

1Check out to specific local branch

 Herokuへデプロイするためにmasterブランチとしてチェックアウトする。

2シェルスクリプト

 Herokuへのデプロイ設定を行う(次のスクリプト)。

Jenkins設定
# herokuというリモート名がない場合は新しく設定する。
# fast-sands-8010.gitは読者の環境に合わせて変更してほしい。
if ! git ls-remote heroku; then
  git remote add heroku git@heroku.com:secure-spire-18515.git
fi
git push heroku master # チェックアウトしたソースをHerokuへPushする。
heroku run rake db:migrate # Heroku上のDBのスキーマ情報を更新する。
リスト9 Herokuへのデプロイ設定

3Only Growl on Failure or Recovery?

 Growlのオプション設定を行う。テストとは異なり、デプロイは毎回報告してほしいので「No」を選択する。

 circle_unit_testを実行すると、3つのジョブが順次実行されるのが確認できると思う。これで「開発→テスト→デプロイ」という手順が自動化された!

ビルドパイプラインの可視化

 「パイプラインを構築したのはよいが、イマイチ各ジョブの関連性が分かりづらい……」、そんなときは「Build Pipeline Plugin」を導入してみよう(図20)。

図20 プラグインを導入しているところ

 このプラグインをインストールできたら、新たなビューを作成してみよう(図21)。

図21 [+]タブをクリックして新たなビューを作成する

 次に、図22のように[ビュー名]を指定し、[Build Pipeline View]を選択して[OK]ボタンをクリックする。

図22 ビュー名を「circle」として、[Build Pipeline View]を選択

 その後のビューの設定は次の通りだ。

図23 ビューの設定を行う

 具体的には[Select Initial Job]の設定を変更するだけでOKだ。

[保存]ボタンを押すと、新たなビューが作成されると思う。

図24 Build Pipelineビューが作成される

 うまくビューが表示されたら、上の画面のように[Run]アイコンをクリックしてみよう。ジョブ実行時にパネルの色が変化するので見ていて楽しいし、何より各ジョブの関連性が分かりやすい。

まとめ

 これで、Gitでpushするだけでテストからデプロイまで一貫して行えるようになった。Jenkinsを導入する前と比較すると、格段に作業効率が向上していると思う。

 しかし、戦いはこれからだ。Gemのバージョンアップで下位互換性が失われたり、慌てて行ったバグ修正で新たなバグを産んでしまったり、ひっきりなしにJenkinsからエラー通知が飛んできたりするかもしれない。そんなときは慌てず騒がず、ビルドが失敗している原因を確実につぶしていこう。チームメンバー全員がプロジェクトのビルド状況を把握していれば成果物もより良いものになっていくだろう。明日の天気予報よりジョブの天気マークが気になってきたら、君もJenkins使いの仲間入りだ!

 さて、次回は肥大化するテストをどのように分散化するかを説明する。楽しみにしておいてほしい。

Jenkins入門【2.0対応】 - オープンソースCIツール(3)
1. Jenkinsをインストールして使ってみよう[Mac/Linux/Windows]

継続的インテグレーションツール「Jenkins」の使い方を基礎から解説する連載がスタート。初回は、Jenkinsの概要とインストール手順、簡単なジョブの登録方法を説明する。

Jenkins入門【2.0対応】 - オープンソースCIツール(3)
2. Jenkinsでテストを実行してみよう+Rubyテストの基礎(RSpec&Turnip使用)

Jenkinsを使って小さなテストを自動実行して、開発スピードを飛躍的に向上させよう。また、MacでのRuby/Rails環境の構築方法から、テストフレームワーク「RSpec」とインテグレーションテスト環境「Turnip」を使ったテストの書き方までを解説する。

Jenkins入門【2.0対応】 - オープンソースCIツール(3)
3. 【現在、表示中】≫ Jenkinsでアプリケーションをデプロイしてみよう

継続的インテグレーションの手順のうち、デプロイに焦点を当てて、テストの実行から、GitによるHeroku環境へのデプロイまでを自動化する方法を解説。Mac向けのGrowlを使って実行結果を通知する方法も説明。

Jenkins入門【2.0対応】 - オープンソースCIツール(3)
4. Jenkins+Vagrantでテストを分散しよう

テストの分散は、環境を分けたい場合や速度を上げたい場合に役立つ。Vagrantで複数マシンのテスト環境を構築し、Jenkinsから複数マシンにまたがるテストジョブを実行してみよう。また、お勧めの便利なプラグインも紹介する。

Jenkins入門【2.0対応】 - オープンソースCIツール(3)
5. Jenkins 2の新機能「Pipeline」を使ってみよう

何をやっているか分からない「Jenkinsおじさん」の作業を見える化しよう。Jenkins 2に新搭載されたPipelineを使えばパイプラインをコードで記述できるようになる。その基本的な使い方を解説。

サイトからのお知らせ

Twitterでつぶやこう!