«前の日記(2007-02-18 (日)) 最新 次の日記(2007-02-21 (水))»  

まちゅダイアリー


2007-02-19 (月)

Debian Sarge で Capistrano 1.4.0 を動かす

Debian Sarge で Capistrano が動かないという昨日の話の続き。

  • Debian を sid (unstable) にする
  • Debian をやめて Ubuntu にする
  • いっそ Mac OS X にする

とか色々考えた挙句、結局Re: Capistrano and Media Temple (gs) - Grid Serverに書かれている方法で Capistrano のソースを修正して対応した。

$ cd /usr/lib/ruby/gems/1.8/gems/capistrano-1.4.0/lib/capistrano/scm
$ diff -u subversion.rb.org subversion.rb
--- subversion.rb.org   2007-02-20 00:27:50.445393872 +0900
+++ subversion.rb       2007-02-20 00:29:00.804370024 +0900
@@ -20,7 +20,7 @@
       def latest_revision
         @latest_revision ||= begin
             configuration.logger.debug "querying latest revision..."
-            match = svn_log(configuration.repository).scan(/r(\d+)/).first or
+            match = svn_info(".").scan(/Revision: (\d+)/).first or
               raise "Could not determine latest revision"
             match.first
           end
@@ -87,6 +87,10 @@
           `svn log #{authorization} -q --limit 1 #{path}`
         end

+        def svn_info(path)
+          `svn info #{path}`
+        end
+
         def svn_password
           configuration[:svn_password] || configuration[:password]
         end

svn log --limit 1 の代わりに svn info を使ってリビジョン番号を取得している。 なるほど。

これでもう一度、 deploy に挑戦。

$ cap deploy
  * executing task deploy
  * executing task update
 ** transaction: start
  * executing task update_code
  * querying latest revision...
  * executing "if [[ ! -d /home/machu/deploy/releases/20070219153034 ]]; then\n              svn co   -q -r85 ssh+svn://example.com/svn/test_capistrano /home/machu/deploy/releases/20070219153034 &&\n              (test -e /home/machu/deploy/revisions.log || (touch /home/machu/deploy/revisions.log && chmod 666 /home/machu/deploy/revisions.log)) && echo `date +\"%Y-%m-%d %H:%M:%S\"` $USER 85 20070219153034 >> /home/machu/deploy/revisions.log;\n            fi"
    servers: ["localhost"]
    [localhost] executing command
    command finished

      (中略)

 ** transaction: commit
  * executing task restart
  * executing "sudo  /home/machu/deploy/current/script/process/reaper"
    servers: ["localhost"]
    [localhost] executing command
 ** [out :: localhost] Couldn't find any pid file in '/home/machu/deploy/current/tmp/pids' matching 'dispatch.[0-9]*.pid'
 ** [out :: localhost] (also looked for processes matching "/home/machu/deploy/current/public/dispatch.fcgi")
    command finished

今度は成功したっぽい。ただ、 deploy 先でサーバが動いていなかったので、サーバの再起動には失敗してる。 まぁ、これは今回はいい。

次に、 deploy 先を見てみる。

$ ls -l ~/deploy
total 12
lrwxrwxrwx  1 machu machu   42 Feb 20 00:30 current -> /home/machu/deploy/releases/20070219153034/
drwxrwxr-x  3 machu machu 4096 Feb 20 00:30 releases/
-rw-rw-rw-  1 machu machu   44 Feb 20 00:30 revisions.log
drwxrwxr-x  5 machu machu 4096 Feb 18 16:18 shared/

current という symlink が、 releases に格納された最新のバージョンを指すようになっている。 バージョンアップしても、最新版は常に current に入っている。

TextDrive の場合、これまでは

~/web/public/

に配置していたコンテンツが、

~/web/public/current/

になっちゃう訳か。 眠くなってきたので、今日はここまで。

やっぱり動かない

こんなことやってみたけど、デプロイ先に反映されない。

Subversion リポジトリを作って、 Rails アプリを作成。

$ svnadmin create /home/machu/svn/capping --fs-type=fsfs
$ cd ~/work
$ svn co svn+ssh://localhost/home/machu/svn/capping
$ rails -d sqlite3 capping
$ cap --apply-to capping
$ svn add capping/*
$ svn commit -m 'initial setup' capping

config/deploy.rb を修正。

set :application, "capping"
set :repository, "svn+ssh://localhost/home/machu/svn/#{application}"
role :web, "localhost"
role :app, "localhost"
role :db,  "localhost", :primary => true
set :deploy_to, "/home/machu/deploy/#{application}"

deploy 先をセットアップ。

$ cap setup

次に deploy 。ここで失敗する。

$ cap deploy
  * executing task deploy
  * executing task update
 ** transaction: start
  * executing task update_code
  * querying latest revision...
  (中略)
 ** [out :: localhost] ln:
 ** [out :: localhost] `/home/matsuoka/deploy/capping/shared/system' へのシンボリックリンク `/home/matsuoka/deploy/capping/releases/20070220055523/public/system' を作成します
 ** [out :: localhost] : そのようなファイルやディレクトリはありません
    command finished
*** [set_permissions] transaction: rollback

理由は capistrano が最新のリビジョン番号を認識できていないから。

$ svn info . | grep Revision
Revision: 0

$ svn info config | grep Revision
Revision: 1

最初にチェックアウトした時点でリビジョン0。 rails コマンドでひな形を作ってリビジョン1。 カレントディレクトリはリビジョン0で、それ以外のディレクトリはリビジョン1という扱いになってる。

だから、こうすると(今回は) deploy できる。

$ cd config
$ cap -f deploy.rb deploy

でも、 script/generate でモデルを作ってリビジョンが2になったら、 cap deploy で反映されなくなる。 (configディレクトリのリビジョンが1のままだから)

これは Subversion が古い (1.1.4) から?よく分からない。 しかも、最新の Subversion をソースから入れようとしたら、 apr のバージョンが古いと怒られた。 本当に OS の乗り換えを検討するかな…。

Capistrano の使い方

せっかくなので、(まだ動かないけど) Capistrano の使い方をメモ。

基本タスク

Capistrano で使えるタスクの一覧は、以下のコマンドで調べられる。

$ cap show_tasks

個人レベルで使うなら、とりあえずこれだけ覚えればよさそう。 いちおう、 Rails 前提で。

cap setup
一番はじめに実行する。 deploy 先に必要なディレクトリをセットアップする。
cap deploy
deploy 先を最新のバージョンに更新する。 script/process/reaper を使って Rails サーバも再起動してくれる。
cap deploy_with_migrations
deploy するときに migrate も実行してくれる。
cap rollback
deploy 先のアプリを一つ前のバージョンに戻す。

deploy は内部で update, update_code, set_permissions, symlink, restart という他のタスクを呼んでいるっぽいから、最初はこれらのタスクを個々に呼んで挙動を覚えた方がよさそう。 慣れてきたら必要に応じて、 config/deploy.rb に自分好みのタスクを書いていけばよさそう。 config/deploy.rb には、はじめからサンプルが入っている。

desc "A task demonstrating the use of transactions."
task :long_deploy do
  transaction do
    update_code
    disable_web
    symlink
    migrate
  end

  restart
  enable_web
end

これは deploy に時間がかかる時に、 disable_web で一時的にメンテナンス画面を表示するものみたい。 こんな感じでいろいろとカスタマイズできるのは魅力的。

sudo を使わない設定

なんだか使ってみようという人が増えて嬉しい。

「deploy実行するユーザーがsudo使えないとダメ」ってのは、 sudo 使わないオプションを指定すればよさそう。 cap show_tasks の spinner のところに書いてあった。 (deploy はサーバを再起動するために、内部で spinner を呼んでる)

Start the spinner daemon for the application (requires script/spin). This will use sudo to start the spinner by default, unless :use_sudo is false. If using sudo, you can specify the user that the spinner ought to run as by setting the :spinner_user variable (defaults to :app).

config/deploy.rb に一行追加して、結果を比べてみる。

set :use_sudo, false

sudo を使う設定の場合(デフォルト)

$ cap deploy
  * executing "sudo  /home/machu/deploy/capping/current/script/process/reaper"

sudo を使わない設定の場合 (:use_sudo が false)

$ cap deploy
  * executing "/home/machu/deploy/capping/current/script/process/reaper"
本日のツッコミ(全3件) [ツッコミを入れる]
niraikanaibird (2007-02-20 (火) 12:13)

こんにちはー。たこめもの者です。<br>:use_sudoをfalseにしてdeployできました。<br>情報ありがとうございますー。

akm (2007-02-21 (水) 02:10)

お世話になります。あまきた日記ですー。<br>僕もDebian Sargeでやってますが、subversion.rbなしでrake deployできました。<br>Capistrano v1.4.0、svnは1.4.2、rubyは1.8.5(testing)を使ってます。

まちゅ (2007-02-21 (水) 14:28)

>niraikanaibird さん<br>どもですー。<br>レンタルサーバでcapistrano使おうとしてたので、ちょうど僕も同じ設定が必要になってました。<br><br>>akmさん<br>どもですー。<br>やっぱりtestingにすれば動くのですね。<br>ノートPCのVMwareで使っている Debian にて、これから挑戦してみます。