RailsをApache上で動かすためのモジュールPhusion Passenger

Rails(3.0.10)をPhusion Passenger上で動かしたときのメモ。サーバーはさくらインターネットVPS、OSはCentOS

Phusion Passengerは、RailsApache(WEBサーバー)上で動かすためのApacheモジュール。Railsを動かすためのWEBサーバーは、開発環境ではWEBrick、本番環境ではMongrelが使われることが多かったが、これらは簡単に使える反面、動作速度やメモリ使用量ではイマイチだった。また、Apacheが入っているのに、Rails専用のWEBサーバーアプリケーションを別個にインストールしないといけないのもイマイチだった?というのが、Phusion Passengerが開発された背景なんだと思う。(WEBや書籍を斜め読みした。)

他のWEBサーバーと比べて動作速度やメモリ使用量の違いは一目瞭然。

Advantages of using Passenger + Apache over Webrick - stackoverflow

公式ページでもベンチマークをガッチリやっている。

手順は以下の通り。

  1. Passengerをインストールする
  2. Apacheの設定ファイル(httpd.conf)を編集する
  3. Railsのサンプルアプリを作成する

1. Passengerをインストールする

以下のコマンドを実行する。

$ gem list passenger         # Passengerが入っていないことを確認
  
  *** LOCAL GEMS ***
  # 何も表示されない。
  
$ sudo gem install passenger # Passengerのgemをインストール
  ...
$ sudo passenger-install-apache2-module # Apacheのモジュールをインストールするコマンド
  ...  
  Installation instructions for required software
  
   * To install Curl development headers with SSL support:
     Please run yum install curl-devel as root.
  
   * To install Apache 2 development headers:
     Please run yum install httpd-devel as root.
  
   * To install Apache Portable Runtime (APR) development headers:
     Please run yum install apr-devel as root.
  
   * To install Apache Portable Runtime Utility (APU) development headers:
     Please run yum install apr-util-devel as root.
  
  If the aforementioned instructions didn't solve your problem, then please take
  a look at the Users Guide:
  
    /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.9/doc/Users guide Apache.html

インストールにはもっとソフトウェアが必要と言われてインストールが中断されるので、足りないものをインストールして再実行。僕の場合は上記のライブラリ。

# 足りないライブラリをインストール
$ sudo yum install httpd-devel
$ sudo yum install apr-devel
$ sudo yum install apr-util-devel

# 再度passenger-install-apache2-moduleを実行
$ sudo passenger-install-apache2-module
  ...
  The Apache 2 module was successfully installed.
  
  # Apacheの設定ファイルへ追記する その1
  Please edit your Apache configuration file, and add these lines:
  
     LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.9/ext/apache2/mod_passenger.so
     PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.9
     PassengerRuby /usr/local/bin/ruby
  
  After you restart Apache, you are ready to deploy any number of Ruby on Rails
  applications on Apache, without any further Ruby on Rails-specific
  configuration!
  
  Press ENTER to continue.
  
  # Apacheの設定ファイルに追記する その2
  --------------------------------------------
  Deploying a Ruby on Rails application: an example
  
  Suppose you have a Rails application in /somewhere. Add a virtual host to your
  Apache configuration file and set its DocumentRoot to /somewhere/public:
  
     <VirtualHost *:80>
        ServerName www.yourhost.com
        DocumentRoot /somewhere/public    # <-- be sure to point to 'public'!
        <Directory /somewhere/public>
           AllowOverride all              # <-- relax Apache security settings
           Options -MultiViews            # <-- MultiViews must be turned off
        </Directory>
     </VirtualHost>

2. Apacheの設定ファイル(httpd.conf)を編集する

インストールが終了すると、Apacheの設定ファイル(httpd.conf)に何を書けばよいか、わかりやすく提示してくれた(上記のログ)。さっそくその通りに編集してみる。

$ sudo vi /etc/httpd/conf/httpd.conf # httpd.confの編集
  ...
  
  # Dynamic Shared Object (DSO) Support
  ...
  # Passenger
  LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.9/ext/apache2/mod_passenger.so # 追記
  PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-3.0.9 # 追記
  PassengerRuby /usr/local/bin/ruby                               # 追記
  ...
  
  # VirtualHost example:
  # Almost any Apache directive may go into a VirtualHost container.
  # The first VirtualHost section is used for requests without a known
  # server name.
  
  <VirtualHost *:80>
     ServerName wwwXXXXXX.sakura.ne.jp
     DocumentRoot /var/www/demo/public            # Railsアプリケーション直下のpublicフォルダを指定
     <Directory /var/www/demo/public>
        AllowOverride all                         # ディレクトリごとの設定(.htaccessファイル)での上書きを許可する
        Options -MultiViews                       # MultiViewsを有効にする
     </Directory>
  </VirtualHost>

$ sudo /etc/init.d/httpd restart # Apacheを再起動

VirtualHostのところの設定が何を意味しているかわからなかったので調べてみた。

そもそもVirtualHostとは、ひとつのサーバーで複数のドメイン名のWEBサイトを運用するための仕組み。たとえば、www.myapp1.comとwww.myapp2.comのドメインを同じサーバーで運用することができる。詳しくはバーチャルホストの例 Apacheを参照のこと。

Directoryの「AllowOverride all」は、httpd.confの設定をユーザーによる設定で上書きできるかということ。ユーザーによる設定は、ディレクトリごとに.htaccessファイルを作って設定内容を書き込むことでできる。.htaccessファイルの詳細は、バーチャルホストの例 Apacheを参照のこと。

同じくDirectoryの「Options -MultiViews」は、HTTPのリクエストヘッダによって適切なコンテンツを返す設定を有効にするという意味。たとえば、Accept-Languageヘッダ値に「en」が優先されていれば英語版のファイル、「ja」が優先されていれば日本語版のファイルを送り出すようなことができるようだ。ITmedia エンタープライズ : Linux Tips「ApacheのMultiViews機能ってなに?」

DocumentRootには、Railsアプリのディレクトリを指定する。

3. Railsのサンプルアプリを作成する

前回、最新(3.1.1)のRailsをインストールしたが、手元の書籍のRailsのバージョンは3.0.xだったので、まずはダウングレードする。

$ rails -v
  Rails 3.1.1
$ sudo gem install rails --version 3.0.10 --no-rdoc
$ sudo gem uninstall rails --version 3.1.1
$ rails -v
  Rails 3.0.10

そして、アプリケーションを新規に作成する。

$ cd /var/www/html
$ sudo rails new demo -d mysql # DBを指定してアプリケーションを新規作成
$ cd demo
$ sudo bundle install          # 足りないライブラリをインストール
$ sudo rails generate scaffold Post name:string title:string content:text # Postという名前のモデル、ビュー、コントローラーの一式を作成
$ sudo rake db:create RAILS_ENV=production      # DBを新規作成
$ sudo rake db:migrate RAILS_ENV=production     # テーブルを新規作成

ブラウザでhttp://wwwXXXXXX.sakura.ne.jp:3000/postsを開いて、demoアプリケーションの画面が表示されたのでこれでOK。

と思いきや、上記のやり方だと、アプリケーションのディレクトリやファイルのオーナーはrootになっている。rootだとログファイルにログを書き込めないなどの問題が出る。そこで、logとtmpディレクトリのオーナーとパーミションを変更する。

$ ls -l /var/www/html/demo/log
  -rw-rw-rw- 1 root root   0 Nov 14 23:11 development.log
  -rw-rw-rw- 1 root root   0 Nov 14 23:39 production.log
  -rw-rw-rw- 1 root root   0 Nov 14 23:11 server.log
  -rw-rw-rw- 1 root root   0 Nov 14 23:11 test.log

この状態でURLにアクセスしても、production.logのファイルサイズは0のまま。以下のようにディレクトリのオーナーとパーミションを変更する。

$ cd /var/www/html/demo
$ sudo chown -R montecut:users log tmp # オーナーをmontecutに変更
$ sudo chmod 755 -R log tmp            # アクセス権を設定
$ sudo service httpd restart           # Apacheを再起動

複数人でサーバーを使うことを考えると、本当はオーナーは個人のログインアカウントでない方がいいかも。とりあえず、これでURL(http://wwwXXXXXX.sakura.ne.jp:3000/posts)を開く。その後、ログファイルを確認すると、ファイルサイズが増えていることが確認できる。

$ ls -l /var/www/html/demo/log
  -rwxr-xr-x 1 montecut users   0 Nov 14 23:11 development.log
  -rwxr-xr-x 1 montecut users 251 Nov 14 23:39 production.log
  -rwxr-xr-x 1 montecut users   0 Nov 14 23:11 server.log
  -rwxr-xr-x 1 montecut users   0 Nov 14 23:11 test.log