ishida

2013.11.25

Rails以外のプロジェクトでcapistranoを使う

挨拶

カードファイターの肩書を返上してポケモントレーナーを名乗るべきなんじゃないか疑惑の浮上している石田です。ダブルバトルを見据えておいかぜファイアローを厳選中です。今回は固体値厳選も努力値振りも楽になったので気軽に育成して色んな型を試し易いのが嬉しいですね。現段階では、いばみがクレッフィと輝石ニダンギルとメガガルーラはもうちょっとどうにかならなかったのか?と疑問に思っています。

さてcapistranoについては以前、大佐が書いていましたが、ちょっと被せていこうと思います。理由は、読めばご理解いただけるんじゃないかと思います。capistranoについては色々とWeb上に情報は有るのですが単純にRalisアプリをデプロイさせようとし過ぎていて他のアプリケーションのデプロイ方法を調べようとすると色んなところから情報をかき集める必要があって結構大変だったため、ここにまとめておこうと思います。

capistranoって何?

ひとことで言えばRails用のデプロイツールです。しかし、その実態は 「Role という単位でくくったサーバーグループに対して同じコマンドを同時に発行して結果を受けとったり、一斉にファイルをアップロードするフレームワーク」に「実装例のひとつとしてdeployというRailsアプリをデプロイするためのワークフローを定義したツール」をセットにしたものだと思っています。じゃあ、実際にそのフレームワーク上に色々作るのかというと現状では、まだそんなことはしていないのですが…… それはさておきcapistranoはRubyのツールなのでRubyが必要です。capistranoの現在の最新バージョン(3.0.1)をインストールしようとすると、バージョン1.9以上が要求されます。また、インストールにgemを使います。これらは事前に用意しておいてください。

インストール

これだけですね。ただ、実際に運用する場合、本番環境へのデプロイ以外にも結合テスト環境へのデプロイやステージングへのデプロイ等、デプロイ先を複数定義しておきたいケースの方が多いと思います。capistrano-extという拡張を利用します。ついでなので、capistranoの出力を色分けするcapistrano_colorsも入れておきます。

※ githubの最新版見るとcapistranoのプロジェクトなのに、capistrano-extを前提としたようなディレクトリ構成になっているのが見受けられますが、サーバー構築の事情により古いバージョン入れないとイケないケースも有ると思うので、capistrano-extを入れる前提で進めます。

capistranoのdeployはデフォルトではリモートサーバー上でバージョン管理ツールから最新版をとってきてゴニョゴニョしたりしてデカいプロジェクトをデプロイしようとするとかなり時間かかったりするし、そもそも本番環境のサーバーに余計なもの入れたくねーよということで以下もインストールしておきます。

ということで一旦必要なものは揃いました。では、次にcapistranoを実際触ってみましょう。

capistranoを触ってみる

適当なディレクトリを作って、適当なディレクトリに移って、以下のコマンドを打ってください。

そうすると以下のようなファイルとディレクトリが作られます。

一旦、マルチステージモード(capistrano-ext)については無視して進めます。config/deploy.rb を開いてください。とりあえず、いっぱい書いてあるのは消して、以下の記述だけにします。

定義できたら、以下のコマンドを叩いてみてください。

このコマンドを叩くとconfig/deploy.rb に role:web で 定義されているサーバー群に一斉にコマンドを発行するcapistranoのシェルを起動します。とりあえず、ここではlocalhost 一個だけですが、とりあえずコマンドを発行してみましょう。

何らかの結果が返ってきたんじゃないかと思います。ちょっと遊んだら適当にexitしてください。ここで適当に繋げるサーバーがある人は以下のようにconfig/deploy.rbに追加してみてください。また、別のroleを適当に追加してみたりしても良いでしょう。

同時に色々コマンドを発行して「こういうモノか」と慣れてみてください。慣れたら、次にタスクを定義してみます。shellがサーバーに対して一斉にコマンドを発行するshellならば、taskは一斉にサーバー上で実行するシェルスクリプトのようなモノだと思ってください。ただし、色々コマンド発行して気付いたと思いますが、ひとつのコマンドを発行すると状況がリセットされます。ひとつのコマンドを発行して1セッション、次のコマンドを発行して1セッション。”ssh -2 HOST_NAME ls -al” を一斉に発行して整形して出力しているようなものだと思うと理解し易いんじゃないかと思います。では、config/deploy.rb の role定義の下あたりに以下のコードを貼り付けてみてください。

これは /tmp へ cd したあとに ls -al するというシェルスクリプトを :web で定義されているrole へ一斉に発行するというタスクを定義したものです。編集し終わったら以下のコマンドを叩いてみてください。

想像通りの結果が得られたんじゃないでしょうか。ここまでやってみて大体アタリが付いたのではないかと思いますが、capistranoのデプロイツールとしての側面は、capistranoフレームワークを使ってRailsアプリ向けのデプロイ用のタスク群を定義した実装のひとつであると。では、次にそのdeployクラスについて見ていきましょう。

deployクラスについて

deployクラスはRailsのデプロイ用のタスクをワークフローとして定義しているクラスです。Railsのアプリをデプロイするには何も弄らなくても良いらしいのですがRails以外のプロジェクトで使うには実行しなくて良いタスクとか有るので潰しておいたりします。以下はdeployに定義されているタスクです。cap -T というコマンドで見れるのですが実行順とか含めて説明したいので敢えて書きます。

deploy:update

deploy:update_codeを実行したあとにdeploy:symlinkを実行してるんだと思う

  deploy:update_code

バージョン管理ツールからコードをとってきて各サーバーへ反映

  deploy:symlink

各サーバーのcurrentシンボリックリンクを貼り変え

  deploy:finalize_update

sharedに配置する静的ファイル等のシンボリック作成処理

deploy:migrations

Railsのdb:migrateを実行するんだと思う

deploy:restart

Apacheの再起動なんだと思います。他にstartとstopというのも有ります。

多分、上記taskを読んでみても「シンボリック?んん?」みたいによく分からない感じだと思うので、詳しく説明するとcapistranoのdeployは以下のような仕組です。cap deploy:setup コマンド(リモートサーバーにデプロイ環境を整えるための準備用コマンド。初めの一回目に打つ)を打つと /path/to/deploy が以下のようになります。

そしてreleasesに以下のようにデプロイごと(cap deployを打つごとに)にバージョンが積み重ねられていきます。バージョン名は実際には日付及び時間を元に決められるのですが、ここでは分かり易くするためにver1,ver2,ver3のようにしておきます。ここではver3が最新版ですね。

/path/to/deploy/current のシンボリックリンクは最新版、つまりver3に向けられています。つまり、1、ソースをとってくる 2、releasesに最新版のコピーを作る 3、currentを最新版のディレクトリのシンボリックリンクを貼り変える。 というのが大まかなデプロイの流れです。それを踏まえた上でタスクの一覧を見てみると理解が深まるんじゃないかと思います。つまり、デプロイ後に最新バージョンが事故ってソースをロールバックしたい場合にはデプロイをし直さなくてもシンボリックリンクをひとつ前に書き変えるだけで良いので高速だし安心ですね。ダウンタイムを減らせます。

さて、以上を踏まえた上でRails以外、例えばPHPのプロジェクトなどをデプロイするのであれば要らなそうなタスクをオーバーライドして潰しておきます

deployの設定項目とcapistrano-extについて

これは実際に見てもらって方が早そうなので、載せちゃいます

deploy.rbの例

というところです。ジェネレート直後には、role:db とか、role :appがどうとかありますが、DBのマイグレーションをcapistrano上でしない前提なので不要です。webだけで良いです。さて、はじめに話題にしたcapistrano-extがここで出てきます。現状のままだと、role が deploy.rb上で固定になってしまっているので、staging や prodution で切り替えることが出来ません。そこで、roleの行を以下のように書き変えます。

次にdeploy/production.rb というファイルを作ってroleの設定をそちらに移します

さらにdeploy/staging.rb というファイルを作ってstaging用の設定をそちらに記述します

こうすることで以下のようにコマンドを打つことで、デプロイ先を切り替えたデプロイが出来るようになります

でも、これだけではデプロイ先を切り替えても環境設定ファイルが切り替えられないよ(><)という感じですね。capistrano-extには"cap multistage:prepare" というスタブが有って、これをオーバーライドして切り替えろということなのだと思うのですが、上手く機能させられなかったので、finalize_updateを利用しています。finalize_updateだとデプロイをしてしまったあとの切り替えになってしまって少し微妙なのですが瞬断ですら無いと思うので良いことにしてください。バージョン管理ツールにstaging用、production用の設定ファイルを引っ掛けておいて、runを使ってコピーするのが良いと思います。多分、ここまで分かっていれば調べながら使い始めることが出来ると思います。この記事がそのキッカケになれば幸いです。勿論慣れてくれば自分で完全にdepoyクラスを作ってしまうことも可能ですし、流れはそのままにちょっとオーバーライドしてRubyのコードを書けば、かなり柔軟なことが出来ると思います。実はまだdeployクラスについては使いこなせているというほどではないため間違いを書いているかも知れません。有識者の方はMessageLeafからツッコミとかしてもらえると嬉しいです。

終わりに

アライドアーキテクツでは自分だってまだ使い始めたばかりで内部の実装まで詳しく掘り下げられていないクセにエラそうに上から目線の記事を書いてしまうエンジニアと、ポケモンマスターを募集しております