まちゅダイアリー

Rails 勉強会 - capistrano を使ってみる

2007-02-18

せっかく勉強会で覚えたし、 capistrano を使ってみよう。 自動化大切。

インストール

RubyGems を使ってインストールできる。

$ gem install capistrano

Ruby から ssh や sftp を操作するパッケージが一緒にインストールされる。

使い方

capistrano をインストールすると、 cap というコマンドが使えるようになる。 この cap コマンドを使って、 deploy をやることになる。 まだ良く分かっていないけど、たぶんこんな感じ。

  1. Rails のアプリを作る
  2. 「cap —apply-to Railsアプリ名」で Rails アプリを capistrano 対応する
  3. config/deploy.rb ファイルを編集し、 Subversion リポジトリと deploy 先の場所を設定する
  4. rake deploy で deploy 先にアプリをセットアップする

まずは今日のセッションと同じように、ローカルで Rails アプリを作って、ローカルに deploy してみよう。

Rails アプリを作る

test_capistrano という名前で Rails アプリを作る。と言っても中身はまだ空。

$ rails -d sqlite3 test_capistrano
$ svn add test_capistrano
$ svn commit test_capistrano

リポジトリにコミットする。

Rails アプリを capistrano に対応させる

cap コマンドを使って、リポジトリに登録した Rails アプリを capistrano に対応させる。

$ cd test_capistrano
$ cap --apply-to test_capistrano
      exists  config
      create  config/deploy.rb
      exists  lib/tasks
      create  lib/tasks/capistrano.rake

「config/deploy.rb」と「lib/tasks/capistrano.rake」の2つのファイルが作られた。 このうち、「config/deploy.rb」に必要な設定を書く。 「lib/tasks/capistrano.rake」は、 cap コマンドを rake から使うためのラッパーっぽい。

deploy に関する情報を設定

「config/deploy.rb」を編集して、deploy に関する情報を設定する。

set :application, "test_capistrano"
set :repository, "ssh+svn://example.com/svn/test_capistrano/"
role :web, "localhost"
role :app, "localhost"
role :db,  "localhost", :primary => true
set :deploy_to, "/home/machu/deploy"

role は、タスクの対象となるサーバを指定する。 静的ファイルを置く Web サーバと、 Rails アプリを置く AP サーバと、データベースを置く DB サーバを分けることができる。

とりあえずさっき登録したリポジトリの場所と、 deploy 先として localhost を設定する。

deploy する(前準備)

cap コマンドか rake コマンドを使って deploy する。 それぞれのコマンドで使えるタスクは、以下のコマンドで調べられる。

$ cap show_tasks
$ rake -T | grep remote

DB のマイグレーションだけ実行したりもできるみたい。

…と、 deploy する前に、まずは setup コマンドを使って deploy 先にいくつかディレクトリを作る必要がある。

$ rake remote:setup
/usr/bin/rake:17:Warning: require_gem is obsolete.  Use gem instead.
(in /home/machu/work/misc/rails/test_capistrano)
Capistrano/Rake integration is deprecated.
Please invoke the 'cap' command directly: `cap setup'
  * executing task setup
  * executing "umask 02 &&\n    mkdir -p /home/machu/deploy /home/machu/deploy/releases /home/machu/deploy/shared /home/machu/deploy/shared/system &&\n    mkdir -p /home/machu/deploy/shared/log &&\n    mkdir -p /home/machu/deploy/shared/pids"
    servers: ["localhost"]
    [localhost] executing command
    command finished

これで deploy 先に以下のようなディレクトリができる。

+ releases
  + deploy する度にここにタイムスタンプ名のディレクトリが作られる
+ deploy
  + shared
    + system
    + log
    + pids

準備ができたので、ワクワクしながら deploy を実行!

$ rake deploy
/usr/bin/rake:17:Warning: require_gem is obsolete.  Use gem instead.
(in /home/machu/work/test_capistrano)
Capistrano/Rake integration is deprecated.
Please invoke the 'cap' command directly: `cap deploy'
  * executing task deploy
  * executing task update
 ** transaction: start
  * executing task update_code
  * querying latest revision...
svn: invalid option: --limit
Type 'svn help' for usage.
*** [update_code] transaction: rollback
  * [update_code] rolling back
  * executing "rm -rf /home/machu/deploy/releases/20070218071950"
    servers: ["localhost"]
    [localhost] executing command
    command finished
rake aborted!
Could not determine latest revision

(See full trace by running task with --trace)

失敗してる… orz

svn: invalid option: --limit

Subversion に —limit コマンドが無いよっていうエラーみたい。 しかも「Capistrano/Rake integration is deprecated.」ということで、 Rake ファイルから cap コマンドを呼ぶ方法は非推奨みたい。 調べてみたら、 Debian Sarge に入っている Subversion のバージョンが古いことが原因みたい。

「svn log —limit」というコマンドを実行して、最後のコミットのリビジョンを取得しようとしているみたい。 古い Subversion には、この —limit オプションが無いのがエラーの原因。 その行を修正して、他の方法でリビジョン番号を取ってくれば動くらしいけど…。

そろそろ Ruby 1.8.2 じゃ動かないアプリも出てきている (Lingr APIのAPI Clientとか) し、 Sarge を使うこと自体を見直したほうがいいのかな。

追記: 結局、 Capistrano に付属の subversion.rb を修正して対処した。