/etc/init.dからの起動時に環境変数を指定する方法


または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しているからだ。

~~~~ruby:/u/apps/myapp/shared/bundle/ruby/1.9.1/gems/pry-0.9.8.2/lib/pry/pry_class.rb
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
~~~~

あるし。なんで認識しない。

[このひと](http://kjvarga.blogspot.jp/2011/03/solved-installing-passenger-305-apache2.html)も同じ問題か？と思ったが、rvmが~/.rvmを見つけられないという問題でそれをハードコーディングで解決していた。ちょいちがう。

ちなみに、rails cは起動する。pryで。

~~~~ruby
[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
~~~~

=> 治ったｗｗｗ これで解決。

要するにinit.dでinitがデーモンとして起動したプロセスには環境変数HOMEが設定されておらず（他にもいろいろと違いはあるだろう）、それがたまたまpryのコードで爆発したということか。

という理解を元に検索したところ、どうやらApacheで(HOMEじゃなくてPATHだが)同様の問題に遭遇し、解決している人がいた。

> 謎が解けた。
>
> つまり、/usr/local/etc/rc.d 以下の自動起動スクリプトで起動された時は、PATH には /etc/rc で指定されている
>
> PATH=/sbin:/bin:/usr/sbin:/usr/bin
>
> この値がセットされるのだろう。
> で、ユーザが起動した時は、そのシェル上の環境変数 PATH の値がセットされるというわけだろう。
> 
> <cite>http://blog.netandfield.com/shar/2009/09/apache-path.html</cite>


この人はどうもFreeBSDのようだが、Linux(Fedora)の場合 `/usr/local/etc/rc.d`に相当するものは
`/etc/init.d/functions`である。ただ`/etc/init.d/functions`を変更すると他のデーモンにも影響を与えると思うので、`/etc/init.d/nginx`内でやろう。

~~~~cs
root # env | grep HOME
HOME=/root
~~~~

なのでこいつをセットする。nginxのPassengerでpryを起動することはないので、

~~~~bash:/etc/init.d/nginx
HOME=/root; export HOME
~~~~

とすればよい。冷や汗かいた。