更新情報

こんにちは、トランスネットの泉です。

Ruby on Railsで構築したアプリケーションを実際に運用する場合、おそらくWEBrickではないWebサーバを利用することになります。

unicornpumaなど選択肢は色々ありますが、比較的手軽に利用できるものといえばPassengerではないでしょうか。
Ruby on Rails: Deployでも、Passenger aka mod_railsとして取り上げられています。
また、最近ではRaptorのコードネームを持つPassenger5も注目されています。(コラム執筆時点でβ版)

Phusion Passenger

弊社では、ノウハウの蓄積があるApacheにPassengerを組み合わせた環境を数多く運用しています。

enjoy Railsway 第3回は、Apache+Passengerの組み合わせで、複数Railsアプリケーションを様々な環境指定で実行する方法をご紹介します。

※以降、Apache + Passengerについての内容となります

サブディレクトリ運用

一つのWebサーバで複数のRailsアプリケーションを動作させる方法の一つとして、ドキュメントルートにサブディレクトリを構築するような形を取る方法があります。

/var/www/html (ドキュメントルート)
├── app-a -> /var/rails-app/app-a/current/public
└── app-b -> /var/rails-app/app-b/current/public

app-*はそれぞれRailsアプリケーションのpublicへのsymlink

/etc/httpd/conf.d/passenger.confなど:

RailsBaseURI /app-a
RailsBaseURI /app-b

例えば、上記のような設定ではhttp://foo/app-a/http://foo/app-b/ といったURLでそれぞれのアプリケーションが利用できるようになります。

サブディレクトリごとに環境をわけたい – Rubyバージョン

さて、このサーバではRailsアプリケーションはRuby2.1系で動作させているとします。
ここにRuby1.9系で実行する必要があるアプリケーションをデプロイすることになりました。

サブディレクトリごと(アプリケーションごと)に異なるRubyバージョンで動作させたい…
そんな時には、PassengerRubyを設定します。

PassengerRuby

グローバル、及び<VirtualHost><Directory><Location>ディレクティブに指定することで、その階層下で利用するRubyインタプリタを指定することができます。

Phusion Passenger user guide, Apache version 7.4.1. PassengerRuby <filename>

今回のようなサブディレクトリ運用では、以下のように指定できます。

RailsBaseURI /app-v1
<Location /app-v1>
PassengerRuby /usr/local/rbenv/versions/1.9.3-p551/bin/ruby
</Location>

これだけで、http://foo/app-v1/ でアクセスするRailsアプリケーションは、Ruby1.9.3-p551で動作するようになります。

サブディレクトリごとに環境をわけたい – Rails.Env (RAILS_ENV)

続いて「他のRails.envを設定したい」という要求が発生しました。
Passengerで動作するRailsアプリケーションのRails.env(RAILS_ENV)は、デフォルトではproductionとなっています。
サブディレクトリごと(アプリケーションごと)に異なるRAILS_ENVで動作させたい…
そんな時には、RailsEnvを設定します。

RailsEnv

グローバル、及び<VirtualHost><Directory><Location>ディレクティブに指定することで、その階層下で動作するRailsアプリケーションのRails.envを指定することができます。

Phusion Passenger user guide, Apache version 7.4.5. RailsEnv <string>

今回の様なサブディレクトリ運用では、以下のように指定できます。

RailsBaseURI /app-dev
<Location /app-dev>
RailsEnv development
</Location>

これだけで、http://foo/app-dev/ でアクセスするRailsアプリケーションはRAILS_ENV=development として動作するようになります。

組み合わせ

PassengerRubyとRailsEnvは組み合わせて利用することもできます。

RailsBaseURI /app-v1-dev
<Location /app-v1-dev>
PassengerRuby /usr/local/rbenv/versions/1.9.3-p551/bin/ruby
RailsEnv development
</Location>

このように設定すると、http://foo/app-v1-dev/ でアクセスするRailsアプリケーションは、Ruby1.9.3-p551、RAILS_ENV=development として動作するようになります。

注意 – PassengerHighPerformance との併用

Passengerの設定例について調べると、PassengerHighPerformanceを有効にする記述をよく目にします。

PassengerHighPerformance on

 

Phusion Passenger users guide, Apache version 7.6.15. PassengerHighPerformance <on|off>

この記述より下の階層では、PassengerRubyや RailsEnvの指定は機能しなくなってしまいます。
併用する場合はグローバルに記述してしまったりしないよう、注意が必要です。

確認

ここまでの設定を実際に適用して、確認してみます。

/var/www/html
├── app-v1 -> /var/rails-app/app-v1/current/public
├── app-v1-dev -> /var/rails-app/app-v1-dev/current/public
└── app-v2 -> /var/rails-app/app-v2/current/public

上記のようなファイル構成に対し、以下のように設定します。
今回は、/etc/httpd/conf.d/passenger.confとして保存しています。

LoadModule passenger_module /usr/local/rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/passenger-4.0.53/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/local/rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/passenger-4.0.53
PassengerDefaultRuby /usr/local/rbenv/versions/2.1.5/bin/ruby
</IfModule>
RailsBaseURI /app-v2
RailsBaseURI /app-v1
<Location /app-v1>
PassengerRuby /usr/local/rbenv/versions/1.9.3-p551/bin/ruby
</Location>
RailsBaseURI /app-v1-dev
<Location /app-v1-dev>
RailsEnv development
PassengerRuby /usr/local/rbenv/versions/1.9.3-p551/bin/ruby
</Location>
view rawpassenger.conf hosted with ❤ by GitHub

実際にどのような環境で動作しているか確認するために、それぞれのアプリケーションのViewに以下のコードを記述します。

<table>
<tr><th>RUBY_VERSION</th><td><%= RUBY_VERSION %></td></tr>
<tr><th>RAILS_ENV</th><td><%= Rails.env %></td></tr>
</table>

実際に各アプリケーションにアクセスしてみます。

/app-v2

デフォルト(Ruby 2.1.5, production)
v2i

/app-v1

PassengerRubyを指定(Ruby 1.9.3-p551, production)
v1i

/app-v1-dev

PassengerRuby、RailsEnvを指定(Ruby 1.9.3-p551, development)
v1-devi

指定したとおりの環境で動作していることを確認できました:-)

まとめ

PhusionPassengerで複数のRailsアプリケーションをサブディレクトリ構成で運用する場合に、アプリケーションごとにRubyのバージョンやRails.env(RAILS_ENV)を指定する方法をご紹介しました。

VirtualHostを利用した運用がセオリーかも知れませんが、このような運用の方法もあるという参考になれば幸いです。

それでは今日はこの辺で。次回をお楽しみに♪

※ディレクトリごとに異なるRubyインタプリタを指定してデプロイ(bundle install)する方法については、後日ご紹介します
※今回の内容は以下の環境で動作を確認しています:

  • CentOS6.6 Apache/2.2.15 + passenger (4.0.53)