入門 Capistrano 3 ~ 全ての手作業を生まれる前に消し去りたい

はじめに

この記事はGREE Advent Calendar 2013年の21日目です。お楽しみください!

こんにちは、アゴひげがダンディーだと評判の九岡です。GREEでは、JavaやScalaを布教するための土台を固めるため、デプロイや監視の仕組みづくりなどを横断的にやっています。今回はその過程で得られた知識を「Capistrano 3の入門記事」という形で共有させていただきます。

全ての手作業を生まれる前に消し去りたい

この記事ではCapistrano 3の基礎をご紹介します。Capistrano 3はRubyをベースにしたサーバ操作およびデプロイの自動化ツールです。Capistrano 3を利用することで、デプロイなどの複雑なサーバ操作を自動化することができます。ここの記事では、特にデプロイに焦点をあてながら、Capistranoでサーバ操作を自動化する考え方と実現方法をご説明していきます。

Capistrano 3の習得にはある程度の学習コストがかかります。その学習コストを軽くするために本記事を書きました。本記事を読んでいただくことで、みなさんやそのまわりでCapistrano 3が普及して、世界から一つでも手作業が消えたらこれほどうれしい事はありません!

対象

この記事のターゲットは以下のとおりです。

  • Capistranoの概要を知りたい方
  • Capistranoの使ってみたい方
  • 手作業を自動化したい方
  • 既に他のツールで手作業を自動化している

上記のような方がCapistrano 3を使い始めるとき、最初に読んでいただけると捗るような記事を目指しました。

(Capistrano・Ansible・Fabricなどを使って、サーバ操作の自動化を既に行っている方にとっては、目新しいことはないかもしれません)

デプロイはなぜ手間がかかるのでしょうか?

Webサービスなどサーバアプリケーションを利用したサービスをユーザの皆さまにお届けするためには、サーバアプリケーションを開発するだけではなく、実際にそれを稼働させるサーバへデプロイしなければなりません。ところが、このアプリケーションのデプロイという作業には意外と手間がかかります。その理由は、そもそもデプロイに関する要件が多岐にわたるからです。

デプロイの要件とはなんでしょうか?

デプロイの要件は、以下のようなものがあります。

  • アプリケーションの構成要素
  • 実行環境や規模
  • 許容時間
  • 納期はいつまでか
  • 予算はいくら使えるか

アプリケーションの構成要素

どんなプログラミング言語、フレームワーク、ミドルウェアをつかって開発されたアプリか?

実行環境や規模

どんなサーバ何台にデプロイするか?

許容時間

デプロイ開始から終了までにどれくらい時間をかけてよいか?

納期はいつまでか

自動化にかける時間があるのか?

予算はいくら使えるか

自動化にかける初期費用がでるのか?

例えば、毎回おなじプログラミング言語・フレームワーク・ミドルウェアを使って開発して、毎回同じサーバへデプロイするのであれば、話は少し簡単になります。しかし、そうではないところにデプロイの難しさがあります。

手作業でいいのでは?

前述のとおり多岐にわたるデプロイの要件について、わたしたちは自動化または手作業で対応します。

手作業は初期投資が少ないというメリットがある一方、手順書を作成したり作業を実施するための人的コストが継続的にかかったり、繰り返し作業する中でミスが発生する可能性があるというデメリットがあります。自動化したいところです。

自動化すればいいのでは?

・・・と思うところですが、自動化するためにも超えなければならならない壁があります。生産性と保守性についての壁です。

生産性の壁

〜シェルスクリプト? Ant? Ansible? Fabric? Capistrano?〜

新規開発する場合は、独自にデプロイの枠組みを考えるか、OSSなど既存のものを利用するかという選択肢があります。独自につくった部分は実装やテストのコストがかかりますし、かといって既存のものを流用する場合には学習コストがかかります。すこしでも楽に早く実装したいところです。

保守性の壁

〜引き継ぎは?育成は?〜

独自に開発すると、引き継ぎがむずかしい場合があります。設計や実装のポイント、何か設定できて何が設定できないのか・・・。十分なドキュメントを自分で書いて残すことができればいいのですが、時間や予算の都合でスクリプトだけ実装して、ドキュメントはない、ということもあるのではないでしょうか。すこしでも楽に引き継ぎや育成をできるようにしたいところです。

自動化したい

そんなわけで、実際にわたしたちがデプロイを自動化するときには、生産性、保守性、そしてそもそものデプロイの要件のトレードオフを考えなければなりません。これは難しい判断です。仮に「今回は時間がないから手作業でカバー」や「とりあえずシェルスクリプトで自動化しよう。ドキュメントは必要になってから」といった対応になってしまったとしても、それは仕方のないことです。

しかし、理想をいえば、生産性と保守性の壁をこえてサクッと自動化したいですよね。

Capistrano 3ではじめる自動化

前述の生産性と保守性の壁をこえる一つの方法は、学習と引き継ぎのコストを下げることです。そのためにこの記事をお送りします。

期待される結果

Capistrano採用による変化

Capistranoを採用すると、いろいろなサービスのデプロイなどの手順が「Capistranoの設定」という形に統一されます。
それではこのような変化によって、どんなメリット・デメリットが発生するのでしょうか?

メリット

保守性が高い ~maintainable~

シェルスクリプト等だと書いた人によって設計思想が異なるので、設計思想を読み取るところから時間がかかります。Capistranoを知っている人同士であれば、他人の書いたデプロイ設定も読みやすく、結果的に保守や引き継ぎがしやすくなります。

生産性が高い ~productive~

シェルスクリプトだと、使うツールをパッケージマネージャなどでインストール、依存スクリプトはgitで取得、とか色々な配布形態が人や組織によります。書くことはできても、再利用しづらいとか、新しい開発者が来た時にデプロイスクリプトの開発環境整えるのが大変などの問題があります。

RubyライブラリやCapistrano拡張という再配布の形式と、gemやbundlerのようなツールの存在により、デプロイによく使うロジックの再利用がしやすいです。インストールはbundle installすればCapistrano本体・ライブラリ・拡張ふくめて揃います。

柔軟性が高い ~flexible~

既にコマンドの実行手順を書いた手順書や、自動化のためのシェルスクリプトをお持ちでしょうか?Capistranoタスク自体は「コマンドを順番に実行する」だけなので、デプロイのためにシェルスクリプトでやっていたようなことはひと通りできます。nohupでバックグラウンドプロセス化・upstart/monit/daemontools/godなどでデーモン化・プロセス監視・プロセスIDの管理などシェルスクリプトやRubyコードで表現できることであればできます。したがって、デプロイに関していえば、Capistranoにロックインされることにより機能や要件が制限されることは少ないはずです。

読みやすく、書きやすい

まるで英語のような洗練されたDSLでスクリプトを書くことができます。
また、ローカルマシンとサーバへの操作がDSLの文法上、明確に区別されます。まずローカルマシンで何をして、それからサーバで何をして・・・という大局をつかみやすいスクリプトが自然と書けるように強制されます。

デメリット

習得に時間がかかる

確かに時間がかかります。特にCapistrano 3は2013年8月に公開されたばかりです。まだ情報が少ないうえ、日本語の情報となるとさらに限られます。新しいものを覚えるだけでも時間がかかるのに、情報も少ないのでは困ると思います。

そんなみなさんのために、この記事を書きました!この記事を読んでいただくことで、高速にCapistranoを習得できればうれしいです。

まず覚えること

大きく分けて3つを覚えればOKです。

  • Capistranoのモデル
  • Capistranoのワークフロー
  • Capistranoの設定ファイルの書き方

Capistranoのモデル

具体的なコードや設定について知る前に、そもそもどういう枠組みの中で何をするのかという全体像を知っておくと理解が進みやすいと思います。それがすなわちCapistranoのモデルです。プログラムは設計書から、文章は目次から読み始めると全体像が頭にはいって理解しやすかったりしますよね!同じようにツールはモデルから入ってみましょう。

Capistranoのモデルを理解するために最小限必要な単語は以下のとおりです。

  • Capistrano
  • ライブラリ
  • 設定ファイル
  • ホスト

Capistrano

Capistranoはおおまかに以下の3要素から構成されています。

  • capコマンド
  • Capistranoのライブラリ
  • デフォルトのデプロイタスク

わたしたちはCapistranoのライブラリやデフォルトのタスクを利用して設定ファイルを記述して、それをcapコマンドで実行します。すると、Capistranoがもろもろの操作を自動的に行なってくれます。Capistranoがオートメーションのツールであると言われるのはこのためです。

ライブラリ

Capistranoは単なるフレームワークなので、みなさんが開発・利用しているアプリケーション固有のデプロイ方法や、サーバの情報などは含まれていません。皆さんの作業を自動化するためには、Capistranoを皆さん好みにカスタマイズする必要があります。

カスタマイズするにあたって、一度だけ使うものと再利用するものがあると思います。再利用性が高いものはライブラリと呼びます。具体的には以下の2つです。

  • Rubyライブラリ
  • Capistrano拡張

設定ファイル

Capistranoのカスタマイズの際、一度だけ使う設定(例えばあるプロジェクトのサーバ情報、あるプロジェクト固有のタスク)は前述のライブラリではなく設定ファイルに記述します。具体的には以下の2つです。

  • config/deploy.rb
  • config/deploy/任意のステージ名.rb

「deploy.rb」はデプロイ等の共通的な設定や手順を書きます。「任意のステージ名.rb」は本番環境・テスト環境・開発環境などの環境ごとに異なる設定やタスクを書きます。

ホスト

デプロイにあたってコマンドを実行する対象マシンは大きく分けて、「ローカルマシン」と「サーバ」の2つがあります。どこでどのようなコマンドを実行するか決まっているわけではありません。例えばローカルマシンでアプリケーションをビルドして、サーバへアプリケーションをデプロイする、というような使い分けをイメージしていただければわかりやすいと思います。

以上、Capistrano・ライブラリ・設定ファイル・ホストの4つです。この4つはそらでも説明できるように覚えてくださいね!そのあとの詳細なところの理解が格段に進むはずです。

Capistranoのワークフロー

Capistranoを使うためには、いつ、何のために、どんな操作をしてどんなコードを書けばよいでしょうか?その全体の流れをおさらいしておき、それから具体的なコードと操作を覚えていきましょう。

  • Capistranoのインストール
  • 設定ファイルのひな形をつくる
  • 設定ファイルのカスタマイズ
  • capコマンドを実行する

以上の流れにそって、具体的な説明をしていきます。さっそくターミナルを開いて、みなさんの環境に置き換えながら、実際にCapistranoを使ってみましょう!

Capistranoを使ってみましょう

1. Capistranoのインストール

〜コマンド一発でインストールできます〜

RubyGemsをインストールしてあれば、gem install capistranoコマンドを実行するだけでCapistranoのインストールは完了です!もしRubyGemsをroot権限ありでインストールされた場合は、sudoをお忘れなく。

Bundlerをお使いの場合は、Gemfileにgem 'capistrano', '~> 3.0.1'の記述を追加してbundle installを実行しましょう。Bundlerをお使いでない場合は気にしなくてOKです。

2. 設定ファイルのひな形をつくる

Capistranoのインストールが完了したら、Capistranoの設定ファイル配置先となるディレクトリを作成します。名前はなんでもOKです。

そしてcap installを実行することで、前述の「設定ファイル」のひな形が生成されます。

3. 設定ファイルのカスタマイズ

cap installを実行すると、すると前述の「設定ファイル」が生成されます。これをカスタマイズして、自動化を実現します。

4. サンプル設定ファイルの完成イメージ

理解しやすいように、まず完成イメージを共有しておきます。これから、皆さんと一緒にこの完成イメージに向かって設定ファイルの書き方をご説明していきます。

完成イメージは以下のとおりです。現時点ではイメージが掴めなくてもOKです。

config/deploy/test.rb

config/deploy.rb

5. Capistranoデフォルトタスクの消去

まず、Capistranoのデフォルトタスクを全て消します!

前述のとおり、Capistranoにはフレームワークに則ったデフォルトタスクが存在します。デフォルトタスクには、Capistranoの推奨するデプロイ方法に則ったロジックが含まれます。例えばシンボリックリンクで以前のリリース物を残しておくなどです。

ここでシンボリックリンクを使うかどうかといったことは実装の詳細であり、この記事の範囲外ということにします。そうすることで、わたしや皆さんはまず「これまで手動、自動でおこなってきたデプロイをそのままCapistrano化するにはどうしたいいか」というタスクに集中することができます。

Capistranoが推奨するデプロイの仕様を把握し、既存のデプロイ手順をそれに合わせて変更してからCapistranoへ移行するのは手間がかかります。それよりもまず移行してしまってから、必要に応じてCapistranoの推奨スタイルへ徐々に寄せていくほうが容易なはずです。なぜなら、一度に変えなければならないことが少ないからです。それを実現するためには、Capistranoのデフォルトタスクを一度消してしまいます!

Capistranoにはデフォルトで「deploy」というタスクと、それが呼び出す複数の「deploy:サブタスク」が定義されています。Capistranoデフォルトの枠組みの中でデプロイを行う場合は、「deploy:サブタスク」を再定義するだけでよいので便利です。しかし、それらが必要ないので消去します。消去を行っているコードがRake::Task[消去したいタスク名].clearです。実はCapistrano 3はRakeというビルドツールを応用して作られています。taskでタスクを定義して、それをコマンドラインアプリケーションから実行することができるは、Rakeの機能です。今回はその事実を応用して、Rakeの機能を使ってデフォルトタスクを消去します。

デフォルトタスクはCapistrano 3のframework.rakeに定義されています。興味のある方は読んでみてください。

6. config/deploy/ステージ名.rbを書く

ステージ名.rb(今回はステージ名をtestとします)には、ステージ毎に異なる設定を書きます。例えば以下のようなものがあります。

  • そのステージで作業対象サーバ
  • そのステージだけで実行するタスク

典型的なのは、前者の「作業対象サーバ」の設定です。この設定には以下のような情報が含まれます。

  • ホスト名
  • サーバロール
  • ログインユーザ
  • SSH設定
  • その他、そのサーバに紐づく任意の設定

この設定を行うためには、serverという語彙と、
server ホスト名, user: ログインユーザ名, roles: %{サーバロール}, その他の設定: 値, ...という文法を使います。

serverを使って1つのサーバを設定する例を以下に示します。

この一行には以下の設定情報が含まれています。

  • localhost(Capistranoを実行したホスト)を対象にする
  • そのサーバに「Webサーバ」というロールを与える
  • そのサーバへはvagrantというユーザでログインする

7. config/deploy.rbを書く

config/deploy.rbにはステージ間で共通の設定を書きます。よくあるのは以下のような設定です。

  • アプリケーション名
  • レポジトリ名
  • 利用するSCM
  • タスク
  • それぞれのタスクで実行するコマンド

このような設定をDSLで書きます。DSLには以下を定義するための文法と語彙があります。

  • 設定値の変更と取得
  • タスクの定義

設定値の変更と取得

アプリケーション名やレポジトリ名などの設定値はset 名前, 値で設定し、fetch 名前で取り出します。
一度setした値はdeploy.rbやステージ.rbの全域で取り出すことができます。

タスクの定義

個々のタスクはtask タスク名 do; ... endのブロックで記述します。

例えば、:uptimeという名前のタスクは以下のように定義します。

taskブロックの中にはrun_locally do; ... endか、もしくはon 対象サーバ do; ... endブロックを書きます(以後、それぞれ省略してrun_locallyブロック・onブロックと呼びます)。
前者のrun_locallyブロック内にはローカルマシン上で実行するコマンドについて書きます。
また、後者のonブロック内にはサーバ上で実行するコマンドについて書きます。

onブロックの「対象サーバ」の箇所には、前述の「ステージ名.rb」で設定したサーバの条件を指定することができます。
例えば、「Webサーバ(:web)のロールが与えられているサーバ」のみを作業対象とする場合は、以下のように書きます。

executeによるコマンド実行

最後に、実行するコマンドをrun_locallyonブロック内に書きます。
コマンドの実行にはexecute コマンドの文法を使います。
例えば、それぞれのマシン上でuptimeコマンドを実行するためには以下のように書きます。

captureによるコマンド実行結果の取得

executeでコマンドを実行した場合、そのコマンドの標準出力は捨てられてしまいます。標準出力の内容を参照する必要がある場合はcapture コマンドの文法を使います。

単にexecuteをcaptureに置き換えました。captureは引数に渡したコマンドを実行してから、実行結果(標準出力)を文字通りキャプチャして返します。したがって、上記の例ではoutputに標準出力の内容が代入されています。

infoによるログ出力

ただ代入しただけでは意味がありませんので、Capistranoでログ出力してみましょう。ログ出力のためには、run_locallyonブロックの中でログレベルに応じてdebug メッセージinfo メッセージwarn メッセージerror メッセージfatal メッセージの文法を使います。infoを使う場合は以下のようになります。

タスクの定義:まとめ

このように、run_locallyonブロック内ではexecutecaptureinfoをはじめ、いくつかの文法を使うことができます。利用できる文法はこのソースコードで定義されています。

ご紹介していない文法のうちよく使うのは、upload! ローカルファイルへのパス, アップロード先サーバ上のパスです。その名の通りファイルアップロードの機能があります。使い方としては、on 対象サーバ do; ... endブロック内で実行します。すると、Capistranoを実行しているホストから対象サーバへファイルがSCPでアップロードされます。

executecaptureinfoupload!については後の例で使いますので、覚えてきましょう!

7. タスクの例

タスクはローカルマシンで行うもの・サーバ上で行うものを分けて管理するとよいでしょう。それぞれいくつか例を挙げます。

ローカルホストで行うことの例

deploy.rbやステージ名.rbに書くタスクには以下のようなものがあります。

  • ソースコードの取得
  • ビルドとアーカイビング・パッケージング

ソースコードの取得

アプリケーションをデプロイする前に、どこかのタイミングでアプリケーションのソースコードを取得する必要があります。

例えば、Gitを採用しているプロジェクトであれば、以下のような設定でソースコードを取得します。

この例では、:updateというタスクを実行することでソースコードを取得します。後にアプリケーションをローカルマシンでビルドするため、ソースコードはローカルマシンに置くことにします。そのために、前述のrun_locallyブロック内でgitコマンドを実行します。

run_locallyブロック内では、ソースコードの保存先ディレクトリの有無によって、git clonegit pullを使い分けています。
ディレクトリの有無によって場合わけをするためには、Rubyのif文とCapistranoのtest ファイルテストを使います。

ソースコードをまだ取得していない場合は、git clonerepo_urlで設定したレポジトリからソースコードを取得します。保存先はapplicationに設定したディレクトリへしています。

ソースコードが既に存在する場合は、clone時に作成したディレクトリへ移動してから、git pullで更新するようにしました。

ビルドとアーカイビング・パッケージング

ソースコードのコンパイルやその他アセットの前処理を行い、結果をtarballやzip・war・debianパッケージなどの再配布可能な形式にします。
例として、前述のFinagleを使ったサンプルアプリを先ほど取得したソースコードからビルドし、アーカイブする例は以下のようになります。
ここでは、アーカイブ作成のためにsbtというビルドツールと、sbt-packというsbtプラグインを利用します。これら2つについては、本記事の範囲外なので説明は省略させていただきます。興味のある方は、「scala sbt」などで検索してみてください!

順を追って見て行きましょう。まず、task :archive => :update doのようにタスク名archiveの次に=> :updateという記述が続いています。これはタスクの依存関係を表して、「archiveを実行する前にupdateを実行する必要がある」という意味です。実際にarchiveタスクを実行すると、Capistranoは(厳密にはCapistranoの基礎になっているRakeが)この依存関係を考慮して、updateを自動的に実行してからarchiveタスクを実行します。この機能によって、私たちはタスクの依存関係の管理をCapistranoに任せることができます。

次にrun_locallyブロックです。ブロックの冒頭では、sbtsbt-packを使って先ほど取得したソースコードをビルドしています。sbtはビルドが終わった後、作成したアーカイブへの相対パスを標準出力へ以下のように出力します。

このファイルは後でアップロードしたいので、標準出力をキャプチャして正規表現で相対パスを抜き出し、絶対パスへ変換しています。

また、キャプチャ結果のうち/\e\[\d{1,2}m/という正規表現にマッチした部分文字列を消去してしまうコードが含まれています。これはエスケープシーケンスの消去をしています。sbtは実行環境によってANSIエスケープシーケンスを利用してログに色をつけてくれます。今回は後のアップロードのためにアーカイブのパスを抜き出そうとしていますが、エスケープシーケンスもパスの一部と解釈されてしまいます。そこで、このようにエスケープシーケンスだけを消去しています。

コード例の最後では、setを使って後続のタスクが必要とする設定を保持しています。この設定値は後でfetchで取得するので、覚えておいてください!

リモートホスト上で行うこと

リモートホストに対して行うタスクには以下のようなものがあります。

  • アプリケーションのアップロード・インストール
  • アプリケーションの起動・停止
  • Webサーバやロードバランサの操作
  • 監視の開始、停止

今回は、最低限必要なアプリケーションのアップロード・インストールおよび起動・停止について説明します。

アプリケーションのアップロード・インストール

アプリケーションを起動するためには、まずアップロードする必要があります。
例として、前述のFinagleを使ったサンプルアプリをアップロードするには以下のような記述をします。

アプリケーションの起動・停止

実行環境や採用するフレームワークによっては、Webサーバやアプリケーションサーバとは独立してサーバアプリケーションとして動くものもあります。

例えば、以下のようなものです。

  • java・nodeコマンドなどでアプリケーションそのものを起動する場合
  • Play framework・Finagle・Akkaなどのフレームワークなど組み込みのサーバがあるもの

例として、前述のアップロード・インストールのあと、アプリケーションを起動するには、以下のような記述をします。

tarコマンドでアーカイブを展開するところまでは、前述のアップロード・インストールの例と同じです。
そのあとは、「アーカイブに含まれていたディレクトリ/bin/アプリケーション名-バージョン」という名前の起動スクリプトを簡単にファイルグロブでマッチングさせ、実行しています。

例では、project_dirという変数に「アーカイブに含まれていたディレクトリへのパス」を代入しています。
また、launchという変数に起動スクリプトへのパスを代入しています。最後にnohupコマンドを使ってその起動スクリプトを実行しています。
nohupを使っているのは、起動スクリプトをバックグラウンドで実行し続けるためです。
CapistranoはSSHで対象サーバへ接続してコマンドを実行しますが、その後に接続を切ります。その際に、起動スクリプトにSIGHUPシグナルが送信されて起動スクリプトが終了してしまいます。
それを防ぐためにnohupを使っています。

さて、これで完成・・・ではありません。
何かお忘れではないでしょうか?

実はここまでの例では、アプリケーションを初めてデプロイすることしか想定できていませんでした。既にデプロイしたアプリケーションが動作中の場合、それをまず停止する必要があります。アプリケーションを停止する一つの方法は、プロセスをkillしてしまうことです。プロセスはプロセスIDで区別できます。しかし、前回起動したアプリケーションのプロセスIDはいくつでしょうか?

こんなこともあろうかと、前述の例ではアプリケーション起動時にプロセスIDを保存しています。deployタスクのexecuteの最後で、echo $! > RUNNING_PIDというコマンドを実行しているのに気づきましたか?このコマンドで実行したコマンドのプロセスIDをRUNNING_PIDというファイルへ出力しています。

RUNNING_PIDファイルを利用して、2回目以降のデプロイ時には起動中のアプリケーションを停止しましょう。

on_rolesブロックの冒頭にbegin; ...; rescue; ... endブロックを追加しました。
このブロックでは、既にデプロイ済みのアプリケーションのディレクトリ(old_project_dir)がある場合のみ、
RUNNING_PIDファイルからプロセスIDを読み込んで、そのプロセスをkillしています。
これで、2度目以降もデプロイできるようになります。

8. サンプルレシピのまとめ

前述の「サンプルレシピの完成イメージ」をおさらいしてみましょう。
ここまで、以下の完成イメージに向けて設定やタスクの書き方をご説明してきました。
イメージはつかめてきましたか?
これを踏まえて、次の「サンプルレシピの完成形」を読んでみてください。

config/deploy/test.rb

config/deploy.rb

9. サンプルレシピの完成形

これまで説明したDSLを使ったサンプルを以下に示します。
Finagleというフレームワークを使ったアプリケーションの、考えられる限り最も簡単なデプロイ設定です。
Vagrantで作成した仮想マシンで実行し、その仮想マシン自身へログインしてFinagleアプリのソースを取得して、アプリケーションをビルド・インストール・起動します。

config/deploy/test.rb

config/deploy.rb

10. capコマンドを実行する

これまで作成してきたconfig/deploy/ステージ名.rb(サーバを1つ定義しました。今回はステージ=test)とconfig/deploy.rb(タスクをいくつか定義しました)を使って、Capistranoを実行してみます。
Capistranoを実行するためには、前述の「Capistranoのモデル」で触れたcapコマンドを使います。

capコマンドの第1引数がconfig/deploy/test.rbtestの部分に対応します。第2引数がタスク名で、task :deploydeployの部分に対応します。

初回の実行結果は以下の通りです。

11. サーバの状態を確認する

実際にCapistranoでデプロイしたアプリケーションのプロセスを確認してみましょう。

アプリケーションが無事に6908番のプロセスで起動しました。

実際にサーバアプリケーションと通信できるか試してみます。

無事、サーバアプリケーションからHTTPレスポンスが返ってきました。
前述のRUNNING_PIDファイルを使って再デプロイにも対応したので、2回目以降のデプロイも同様にcap test deployを実行するだけです。

12. おつかれさまでした!

今回はFinagleというフレームワークを使ったWebアプリケーションの最も簡単なデプロイを例にご説明しました。

お気づきかもしれませんが、やっていること自体は「タスクとrun_locallyonブロックの中でシェルコマンドを実行する」です。任意のシェルコマンドが使えるので、応用が効きます。この例をカスタマイズしてお好きなコマンドに変更していただければ、皆さんが普段実行している手順をCapistranoのタスクにそのまま置き換えられると思います。また、今回は説明を省略しましたが、Capistranoの中では任意のRubyコードが書けます。シェルスクリプトだけで対応できないような複雑な要件のデプロイなどにも対応できるはずです。ぜひ、トライしてみてください!

まとめ

  • デプロイなどの手作業にはコストがかかります
  • 自動化にも学習コストがかかります
  • 自動化のためにCapistrano 3が利用できます
  • Capistrano 3の学習コストを減らすために、Capistrano 3の基礎を説明しました
  • 例として、Finagleというフレームワークを使ったアプリケーションをデプロイしました
  • この例を応用して、様々な手順を自動化できます。

One more thing

今回はCapistrano 3自体の説明に注力するため、Capistranoの便利機能やデプロイのノウハウは思い切ってカットしました。
今後は以下のようなトピックで、より具体的なレシピをご紹介していきたいと思っています。お楽しみに!

  • ライブラリの使い方
  • Play frameworkなどを利用した実際のアプリケーションのデプロイ方法
  • 無停止デプロイ(Rolling Deploy)

明日はRubyistでありネットワークエンジニアでもある大山さんによるTremaとOpenFlowの記事です。お楽しみに!