CapistranoでUnicornの起動と停止と再起動

ちょっとした気まぐれでUnicornを使ってみた。
初Unicorn。
ということでUnicorn用のCapistranoのタスクをdeploy.rbに書いた。

内容はだいたい以下の受け売り。

namespace :deploy do
  task :start, :roles => :app, :except => { :no_release => true } do
    run "cd #{current_path} && BUNDLE_GEMFILE=#{current_path}/Gemfile bundle exec unicorn_rails -c #{current_path}/config/unicorn.rb -E production -D"
  end

  task :stop, :roles => :app, :except => { :no_release => true } do
    run "kill -KILL -s QUIT `cat #{shared_path}/pids/unicorn.pid`"
  end

  task :restart, :roles => :app, :except => { :no_release => true } do
    run "kill -KILL -s USR2 `cat #{shared_path}/pids/unicorn.pid`"
  end
end

通常の動作ではdeployを実行するとdeploy:updateのあとdeploy:restartされる。
上記のrestartはUnicornが起ち上がってない時は空振りするので、初回deployの時はstartを自分で実行する必要がある。

参考にしたgistだとrestartはstopしてstartしているので空振りはないけど、せっかくUnicornなのにダウンタイム発生させるのももったいないので、空振り上等にしといた。
(UnicornはプロセスにUSR2シグナルを送ると古いプロセスを停止させて、新しいプロセスで起ち上がるという器用なことをしてくれるので、ダウンタイムがなくすことができるそうだ)

2011/08/30追記

USR2シグナルはむやみに送るもんじゃないって分かった。
上記のgistのようにrestartはstopしてstartした方がよい。

その他の参考

完全な余談

ポンとファイルを置くだけで動くPHPとかマジ神。
と、インフラ設定に手こずると思う。
PHPの普及を支えた要素の一つはこういう簡単さなのは間違いないだろうね。

それに比べてRailsのインフラのとっつきにくさといったら・・・
この状況を劇的に改善したPassengerは神ですな。