capistrano + unicornではまった。
以外と語られていないような気がするんだが、railsで capistranoとunicornをつかっていると、思わぬ落とし穴がある。
今まで順調だったcapistranoでのデプロイでunicornの立ち上げが失敗するようになる。 unicornのupgrade(SIGUSR2)がきかなくなった。
upgradeってのは、gracefulなんだけど、
/usr/local/rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/bundler-1.5.2/lib/bundler/definition.rb:23:in `build': /xxxxxxx/releases/日付的なやつ/Gemfile not found (Bundler::GemfileNotFound) from /usr/local/rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/bundler-1.5.2/lib/bundler.rb:152:in `definition' from /usr/local/rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/bundler-1.5.2/lib/bundler.rb:115:in `setup' from /usr/local/rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/bundler-1.5.2/lib/bundler/setup.rb:17:in `<top (required)>' from /usr/local/rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require' from /usr/local/rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
みたいな感じでエラーが出て再起動が出来ない。
解決方法
下記URLのBUNDLE_GEMFILE for Capistrano usersを見ればわかると思います。
capistranoをつかってると、多分、RAILS_ROOT/config/unicorn/production.rb
とか作ってると思うんで、そこに、
before_exec do |server| ENV["BUNDLE_GEMFILE"] = "/path/to/app/current/Gemfile" end
を追記してやる
unicornの実行直前にRAILS_ROOT/current/Gemfile
のGemfileを見るように``BUNDLE_GEMFILE```を差し替えてやればいい。
普通、大体配置は同じと思うんで、さらしておくけど、下記のように出来るかなーと。
before_exec do |server| ENV["BUNDLE_GEMFILE"] = File.join(File.expand_path("../../../../", __FILE__), "current", "Gemfile") end
注意してほしいのは、一回この現象が起きちゃった人、もしくは、対応する前の起動設定で起動しちゃった人は、Unicornをstop startして再起動してあげないとだめ。SIGUSR2
では解決できないと思う。
原因
原因としては、僕はcapistranoで5世代まで昔のディレクトリを保存しておくようにしているんだけど、それが、始めにunicornを立ち上げたディレクトリが消されたタイミングで Gemfile
が存在しなくなってしまうことにある。
capistarano unicornはこんな感じで、unicornを立ち上げる。
RAILS_ENV=vm BUNDLE_GEMFILE=/xxxxxxx/releases/日付的なやつ/Gemfile bundle exec unicorn -c $UNICORN_CONFIG_PATH -E vm -D
この時点でENV["BUNDLE_GEMFILE"]にはRAILS_ROOT/releases/日付的なやつ/Gemfile
が入ってしまうので、これをunicornプロセスが覚え続けてしまう。
そうすると、そのうちSIGUSR2がなげられても、一旦BUNDLE_GEMFILE
の方にGemfile
を確認してしまうので、既に存在しないGemfile
を確認にいってしまう。
そして該当のエラーがでてしまうのだっ! だので対応は、解決方法の所で示した通りだっ!