パーフェクト Ruby on Rails
- 作者: すがわらまさのり,前島真一,近藤宇智朗,橋立友宏
- 出版社/メーカー: 技術評論社
- 発売日: 2014/06/06
- メディア: 大型本
- この商品を含むブログ (4件) を見る
後で書く
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
を確認にいってしまう。
そして該当のエラーがでてしまうのだっ! だので対応は、解決方法の所で示した通りだっ!
unicornとunicorn_railsのオプションの違い
unicorn
とunicorn_rails
はほとんど同じ挙動をして、
application serverを立ち上げてくれますが、一部オプション指定の意味が違います。
ちょっとハマったので書いておくことにします。
結論
unicorn
のオプション-E
はRACK_ENV
を設定unicorn_rails
のオプション-E
はRAILS_ENV
を設定
参考: http://unicorn.bogomips.org/
経緯1
Capistrano 3を導入しまして、unicornを使っていたので無邪気に
を使っていました。(僕の環境では0.3.2) 普通に動かしていたんですが、muninがunicornのmemory statusをうまく取得できていないようでした。
該当のmuninのplugin
pluginに目をちゃんと通すとわかるんですが、
def memory_usage result = { :master => {master_pid => nil}, :worker => {} } ps_output = `ps auxw | grep unicorn_rails` ps_output.split("\n").each do |line|
なるほど。unicorn_rails
でgrepしてます。
ということで、よく調べてみると、sepastian-capistrano3-unicorn
のデフォルトでは
unicorn
を使ってunicornプロセスを起動していて、このままではこのunicorn_memory_status
に引っかからないわけです。
ということで、unicorn立ち上げをunicorn_rails
を通して実行する必要があるわけですがこれはわけなく行えます。
sepastian-capistrano3-unicorn
は、unicorn_bin
というパラメータを用意してまして、これのデフォルトがunicorn
になっているわけなので、ここを変更する。
RAILS_ROOT/config/deploy.rbに下記記述を追記します。
set :unicorn_bin, ->{"unicorn_rails"}
(ラムダで囲んでんのは特に深い意味は無いんですが、評価時にいろいろ変更するようなモノが多いので念のため標準的にこうするようにしています。)
とここで世界は平和に終ると思っていました。
経緯2
unicornの時の-E
パラメータがRACK_ENV
であるということは理解していたので、RAILS_ENV
をunicorn実行前に設定するようにしてたわけです。
こんな感じで
RAILS_ENV=hogehoge; unicorn -E development .....
僕はVM上でrailsを動かすコトが多くて、vm
というRAILS_ENVをつくっていました。
しかしunicorn_rails
に変更してみたら、僕のVMで急にunicornが立ち上がらなくなりました。
RAILS_ENV=vm; unicorn_rails -E development .....
どうも、dababase.ymlにadapterの指定がない的なエラーがはかれていて、おかしーなーと思ったんです。 と、ここで気付きました。
-E
オプションが、RAILS_ENVを上書いていることを。
んで、下記をみた
なるほどね。
以上!