mod_railsを試してみた。

Apache2.2 + mongrel + MySQL構成でRails2.0をいじくるというパターンをはじめてもうすぐ半年になる。最初はRailsのレの字も知らなかったが、JavaでWebアプリつくるのと大体同じことがRailsでできるぐらいのスキルは身についたかなぁと思う今日この頃。(ホントか?)

きっかけ

Railsの気に入らない部分も少しみえてきたわけだが、そのひとつがmongrelサーバ。別につくりが悪いとかそういうことではない。そこまでわかるほどの技術力はまだ私にはない。ただ、とめたり動かしたり、Tomcatと同じぐらいメンドー! ってのがいやだった。それと、mod_proxy_balancer用のapache設定が10行ぐらいになるので、それも面倒だなぁなんて思っていた。あと、極めつけは、mongrelの作者が「もう知らん!」的なことをブログに書いてるという話が気になっていた。

久しぶりに、mongrelFastCGIかなんているレイヤーの話をググってたら、4月ごろmod_railsなんていう真打っぽいやつがでているではないか。しかも、ちょうど数名の勇者たちが既にトライして「イイカンジ」ってレポートを書いてくれている。

早速、私も追随することにした。環境は Ubuntu 8.04。で既にapache2やrails2.0は入っている状態。こちらのページ(http://rails20.jp/2008/04/passenger/)に詳しい手順がのっていたので、書いてある手順に従ってやってみる。

passengerのgem install

passengerというのが何なのかよくわからないが、まずはこれをgemでインストールするらしい。

gem install passenger

これは普通に入った。上記ページではfastthreadを入れるプロセスが書いてあったが、自分はそんな名前のものを入れた覚えがあるのでそこは省略。そして次は、こう打てとある。

passenger-install-apache2-module
root@hoge:~# passenger-install-apache2-module
Welcome to the Passenger Apache 2 module installer, v1.0.5.

This installer will guide you through the entire installation process. It
shouldn't take more than 3 minutes in total.

Here's what you can expect from the installation process:

 1. The Apache 2 module will be installed for you.
 2. You'll learn how to configure Apache.
 3. You'll learn how to deploy a Ruby on Rails application.

Don't worry if anything goes wrong. This installer will advise you on how to
solve any problems.

Press Enter to continue, or Ctrl-C to abort.

へー。 passengerってのは、gemみたいなインストールの仕組みで、gemより親切な感じのやつのことなのだろうか??

Apache apache2-prefork-dev

自分の場合はここで少しひっかかった。

Checking for required software...

 * GNU C++ compiler... found at /usr/bin/g++
 * Ruby development headers... found
 * OpenSSL support for Ruby... found
 * RubyGems... found
 * Rake... found at /var/lib/gems/1.8/bin/rake
 * Apache 2... found at /usr/sbin/apache2
 * Apache 2 development headers... not found
 * Apache Portable Runtime (APR) development headers... found
 * fastthread... found

Some required software is not installed.
But don't worry, this installer will tell you how to install them.

Press Enter to continue, or Ctrl-C to abort.

--------------------------------------------
Installation instructions for required software

 * To install Apache 2 development headers:
   Please run apt-get install apache2-prefork-dev as root.

なになに、apache2-prefork-devなんていうものをapt-getでいれろとな?

なんだか良くわからないが、プロセスをあらかじめforkするような何か開発っぽいものを想起させる名前だ。
ちょっと気にはなったが、調べるのがメンドかったので、とりあえずいれてみる。

apt-get install apache2-prefork-dev

そして気をとりなおして、もう一度。

passenger-install-apache2-module

Apache prefork MPM

すると、今度はこんなメッセージが。

WARNING: Apache doesn't seem to be compiled with the 'prefork' MPM

なんじゃそりゃ?とインストールを中止してググって見ると、apache2系からマルチプロセス管理はMPMなる枠組みとして以下から選択できるようになっているとのこと。

    • worker
    • prefork
    • perchild
    • winnt
    • event

参考: http://www.turbolinux.co.jp/products/server/11s/user_guide/apachempm.html

さっきの警告メッセージには、「コンパイルしなおせ」ってかいてあるけど、まじですか?、apt-getでいれたんだから、そんなのやなんですけど。apt-getの世界でなんとかなるんだよね??ということで、さらにググって見ると、

  • Ubuntuでは 普通にapt-get install apache2とやるとworkerタイプがインストールされる
  • MPMの違うapacheに変えたいときは、apt-getで入れなおせば古いのは消して新しいタイプのをインストールしなおしてくれる

なんてことがわかった。

root@hoge:~# apt-get install apache2-mpm-prefork
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
  apache2-mpm-worker
The following NEW packages will be installed:
  apache2-mpm-prefork
..(略)..

あら、簡単、あっというまにapacheインストールしなおしてくれました。
ログ中で「apacheとめました。」だとか、「起動しなおしました。」だとか、そんなことをいっていたので、
いったんここで半信半疑ブラウザでアクセス。

するとApacheは何もなかったかのように動いている。うーん。ちゃんと入れ替わったのかな?
プロセスを見てみると、apacheの待機プロセス数が前より増えた気がするので、まあ、きっとうまくいってるんだろう。(ホント?w)


しかし、なるほどねぇ。mongrelのレイヤでプロセスたくさん持つかわりに、apacheのレイヤでプロセスたくさん持つようにするってことかな。
しかし、preforkはApache1.3時代のように1リクエスト1プロセスになってしまうのでパフォーマンスは落ちてしまう。まあ、だけど、プロセス共有しない分、変なことが起きたときに影響が広がらずに安定するというメリットがあるわけだし、PHPなんかも原則workerじゃなくてprefork推奨ってことらしいから、まあいいやOKとしよう。


ということで、再挑戦、今度こそインストールできてくれよ。

root@hoge:~# passenger-install-apache2-module
..(略)..
--------------------------------------------
The Apache 2 module was successfully installed.

Please edit your Apache configuration file, and add these lines:

   LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-1.0.5/ext/apache2/mod_passenger.so
   RailsSpawnServer /var/lib/gems/1.8/gems/passenger-1.0.5/bin/passenger-spawn-server
   RailsRuby /usr/bin/ruby1.8

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の設定

インストール完了メッセージ(上記)にご丁寧にApache設定ファイルへの設定追記方法が書いてあったので、
それにしたがってApache設定を書き換える。

まずはモジュールの読み込み部分、

   LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-1.0.5/ext/apache2/mod_passenger.so
   RailsSpawnServer /var/lib/gems/1.8/gems/passenger-1.0.5/bin/passenger-spawn-server
   RailsRuby /usr/bin/ruby1.8

Ubuntuapache文化的には、おそらくこうするのが良いのだろうと思って以下のようにした。

    • mods-available/passenger.load というファイルを新たに作って、上記内容を記述
    • a2enmod passenger と打つ

ちゃんとmods-enabled/にシンボリックリンクがつくられたのを確認できたので、これでよさげ。
あとはRailsアプリのVirtualHost設定(sites-availableの中対応ファイル)のProxyBalancer関連の記述を消しまくり、めちゃめちゃシンプルな設定に変更。VirtualHostディレクティブの中に以下の4行をかいただけ。(ていうか、逆に色々書くと動かなくなりそうな気がしたので、まずはシンプルに・・)

ServerName hogehoge.example.com
DocumentRoot /srv/rails/hogehoge/public/

ErrorLog /var/log/apache2/hogehoge/error.log
CustomLog /var/log/apache2/hogehoge/access.log combined

そしておもむろにapacheを再起動。
mongrelがとまっていて、Service Temporarily Unavailableなんて表示されていたのが、apache再起動すると、Railsアプリが動いた。

おおっ! 
こいつはいいですねぇ。

これから

運用中にコード変更したらどうなるのかとか、そのあたり気になるので、これから実験してみます。