at posts/single.html

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

せっかく勉強会で覚えたし、 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 を修正して対処した。

関連する日記