またはPassenger+nginxでRailsアプリを動かしていたwebサーバを再起動したらnginx起動方法でちょっとハマった件。
Rackエラー出やがる…
さっきまで元気に稼働していたWebサーバーのAMIを作成、完了したのでサーバを再起動。
nginxを起動して、ブラウザからアクセス。
[ pid=1241 thr=11215320 file=utils.rb:176 time=2012-04-29 02:07:46.913 ]: *** Exception ArgumentError in PhusionPassenger::Rack::ApplicationSpawner (couldn't
find HOME environment -- expanding `~') (process 1241, thread #<Thread:0x000000015643b0>):
from /u/apps/myapp/shared/bundle/ruby/1.9.1/gems/pry-0.9.8.2/lib/pry/pry_class.rb:252:in `expand_path'
実行ユーザのHOMEがないと言ってる。
文句を言っているのはpryの内部。何故production環境でpryをロードしているかと言えば、Rails consoleを使い勝手の良いpryにカスタマイズしたいがために、production環境でもpry gemをrequreしているからだ。
252 config.history.file = File.expand_path("~/.pry_history")
こんなくだらない(失礼)とこで…
$ ps aux | grep nginx
root 1276 0.0 0.0 50920 1072 ? Ss 01:54 0:00 nginx: master process /opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
ec2-user 1277 0.0 0.0 51348 2320 ? S 01:54 0:00 nginx: worker process
ec2-user 1279 0.0 0.0 51348 1812 ? S 01:54 0:00 nginx: worker process
$ ps aux | grep Passe
root 1236 0.0 0.0 214096 1868 ? Ssl 01:54 0:00 PassengerWatchdog
ec2-user 1239 0.0 0.0 1014156 2248 ? Sl 01:54 0:00 PassengerHelperAgent
ec2-user 1241 0.1 0.1 214748 10324 ? Sl 01:54 0:01 Passenger spawn server
nobody 1248 0.0 0.0 148212 3740 ? Sl 01:54 0:00 PassengerLoggingAgent
ec2-userで動いているから、こいつのHOMEがあればいいと思うのだが。
[ec2-user@ip-10-160-73-170 ~]$ env | grep HOME
GEM_HOME=/home/ec2-user/.rvm/gems/ruby-1.9.2-p290
MY_RUBY_HOME=/home/ec2-user/.rvm/rubies/ruby-1.9.2-p290
HOME=/home/ec2-user
あるし。なんで認識しない。
このひとも同じ問題か?と思ったが、rvmが~/.rvmを見つけられないという問題でそれをハードコーディングで解決していた。ちょいちがう。
ちなみに、rails cは起動する。pryで。
[ec2-user@ip-10-160-73-170 current]$ bundle exec rails c production
Loading production environment (Rails 3.1.0)
[1] pry(main)>
consoleのケースについてはsshで接続してpryを起動する時は正常にHOMEが設定されているからなにも言われない。
nginxからのつなぎが問題なのか…。
nginxといえば、AMIからのインスタンス立ち上げ時にnginxを自動起動させるため、起動をinit.dに任せたのだった。
しかもgistから拾ってきたばかりのスクリプトで。怪しい!試してみる。
serviceで起動した奴を殺して、直接起動してみる。
$ sudo killall nginx
$ ps aux | grep [n]ginx #=> 動いてないことを確認
$ sudo /opt/nginx/sbin/nginx
=> 治ったwww これで解決。
要するにinit.dでinitがデーモンとして起動したプロセスには環境変数HOMEが設定されておらず(他にもいろいろと違いはあるだろう)、それがたまたまpryのコードで爆発したということか。
という理解を元に検索したところ、どうやらApacheで(HOMEじゃなくてPATHだが)同様の問題に遭遇し、解決している人がいた。
謎が解けた。
つまり、/usr/local/etc/rc.d 以下の自動起動スクリプトで起動された時は、PATH には /etc/rc で指定されている
PATH=/sbin:/bin:/usr/sbin:/usr/bin
この値がセットされるのだろう。
で、ユーザが起動した時は、そのシェル上の環境変数 PATH の値がセットされるというわけだろう。
この人はどうもFreeBSDのようだが、Linux(Fedora)の場合 /usr/local/etc/rc.d
に相当するものは
/etc/init.d/functions
である。ただ/etc/init.d/functions
を変更すると他のデーモンにも影響を与えると思うので、/etc/init.d/nginx
内でやろう。
root # env | grep HOME
HOME=/root
なのでこいつをセットする。nginxのPassengerでpryを起動することはないので、
HOME=/root; export HOME
とすればよい。冷や汗かいた。