Passenger 3でRVMのRubyを使用する
このページでは、Phusion Passenger 3 で RVM を使用する方法を説明します。Phusion Passenger 4 以降はRVMのサポートが大幅に改善されているため、アップグレードすることを強くお勧めします。Phusion Passenger 4 の手順については、こちらのページをご覧ください。
Passenger 3
Passengerは基本的にNginxとApache用の「mod_ruby」です。Passenger 3 アプリケーションをすべて実行するには、*正確に1つの* Rubyを選択する必要があります。複数の Ruby インタープリターを実行する必要がある場合は、最も一般的なものを選択してください。次に、プロキシパスを使用して、Passenger Standalone、Unicorn、Thin、Mongrel、Mongrel2などの外部アプリケーションサーバーに接続し、異なるRubyで異なるアプリケーションを実行できるようにします。これについての詳しい説明(図付き!)は、Phusionのブログの投稿をご覧ください。
Passengerを使用したNginx/Apacheのインストール
まず、passenger-install-apache2-moduleとpassenger-install-nginx-moduleがあります。インストールが完了すると、Webサーバー用のPassengerRuby設定スニペットが出力されます。その値は、インストーラーの実行に使用されたRVM RubyとRVM gemsetに対応するRVM Rubyラッパースクリプトに設定されます。これでPassenger 3の設定に必要なことはすべて完了です!
.rvmrcファイルを作成する代わりに、.ruby-versionまたは.versions.confのような新しい形式のいずれかを使用してください。
echo 1.9.3@my-app-name > .ruby-version
次に、railsプロジェクトで、新しいファイルconfig/setup_load_paths.rbを追加し、RVM 1.12.0(またはhead)以降、RVMはデフォルトのgemsetにgemとしてインストールされているため、$LOAD_PATHをunshiftする必要はありませんが、GEM_PATHを設定する必要があります。config/setup_load_paths.rb.
if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm') begin gems_path = ENV['MY_RUBY_HOME'].split(/@/)[0].sub(/rubies/,'gems') ENV['GEM_PATH'] = "#{gems_path}:#{gems_path}@global" require 'rvm' RVM.use_from_path! File.dirname(File.dirname(__FILE__)) rescue LoadError raise "RVM gem is currently unavailable." end end # If you're not using Bundler at all, remove lines bellow ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', File.dirname(__FILE__)) require 'bundler/setup'
Passenger 3 では、passenger_ruby ラッパーを使用する必要がなく、ruby ラッパー スクリプトを直接使用するようになったことに注意してください。
Passenger Standaloneの起動
次に、Passenger Standalone、つまり 'passenger start'があります。Passenger Standaloneは内部的にNginxを使用し、Nginx構成ファイルにpassenger_rubyディレクティブを書き込みます。このディレクティブは、「passenger start」コマンドの実行に使用されたRVM RubyとRVM gemsetに対応するRVM Rubyラッパースクリプトを指します。
Bundlerの落とし穴
プロジェクトでBundlerを使用すると、Passengerは賢く動作し、Gemfileにリストされているgemのみを$LOAD_PATHに追加しようとします。これにより、(これは開発中にのみ発生するはずですが)リストされていないgemの「ロードできない」エラーが発生する可能性があります。実行時のロードパスを確認するには、
f = File.open('/tmp/load_path', 'w') f.write($:) f.close
をアプリのメインファイル(「require」呼び出しの前)に追加してください。そのロードパスにないgemはロードできません。
トラブルシューティング
- 最も一般的な問題は、適切なラッパースクリプトを取得するためにパスの/bin/部分を忘れることです。
- 次に最も一般的な問題は、passenger_ruby/PassengerRubyの場所に関して、passengerインストールスクリプトの出力に耳を傾けることです。上記で指定したように、ラッパースクリプトの場所を使用するようにしてください。より明確にするために、以下のnginxの例を参照してください。
passenger_ruby /home/wayne/.rvm/bin/passenger_ruby; * NOTICE THE '.rvm/bin' DIR ^ ^ ^ * do NOT use the actual ruby binary in .rvm/rubies/{passenger_ruby}/bin/ruby * do not listen to passenger's output for passenger_ruby as passenger is not aware of rvm.
システム全体(root)インストールの場合、binディレクトリは代わりに/usr/local/rvm/binになります。passenger_ruby /usr/local/rvm/bin/passenger_ruby;
FAQ
-
Q: Passengerで複数のプロジェクトを、各プロジェクトで異なるRubyバージョンで実行できますか?
A: Passenger 3は*1つ*のRubyでの実行のみをサポートしていますが、プロキシパスを使用することでサイト/プロジェクトごとの動作を実現できます。
-
Q: Passengerでカスタムgemsetを使用するにはどうすればよいですか?
A: bundlerを使用しない場合は、config.ruで環境変数を自分で設定できます。例えば:
ENV["GEM_HOME"]=%x{"source ~/.bash_profile ; rvm ree@pancake ; rvm gemdir"}.strip
A: bundlerを使用する場合:gemsetの外にbundlerをインストールし、使用したいgemsetに戻って実行します。bundle install(tmp/restart.txtをタッチして)アプリケーションを再起動します。これは、bundlerが絶対パスを.bundle/environment.rbの中に保存し、bundlerによって直接ロードされるためです。これが期待どおりに機能しない場合は、次のようにbundle installを実行してみてください。
bundle install $BUNDLE_PATH
ユーザーインストールと組み合わせてpassenger-statusのようなコマンドをルートとして実行するにはどうすればよいですか?主に、これを行うための鍵は、次の例に示すように、sudoersファイルでワイルドカードを使用することです。
/usr/bin/env GEM_PATH=* GEM_HOME=* PATH=* passenger-status
これはRVM 1.12.0より前のバージョン用のconfig/setup_load_paths.rbです。
if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm') begin rvm_path = File.dirname(File.dirname(ENV['MY_RUBY_HOME'])) rvm_lib_path = File.join(rvm_path, 'lib') # $LOAD_PATH.unshift rvm_lib_path require 'rvm' RVM.use_from_path! File.dirname(File.dirname(__FILE__)) rescue LoadError # RVM is unavailable at this point. raise "RVM ruby lib is currently unavailable." end end # Pick the lines for your version of Bundler # If you're not using Bundler at all, remove all of them # Require Bundler 1.0 ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', File.dirname(__FILE__)) require 'bundler/setup' # Require Bundler 0/9 # if File.exist?(".bundle/environment.rb") # require '.bundle/environment' # else # require 'rubygems' # require 'bundler' # Bundler.setup # end