Apacheをプロキシ(Proxy)として用いてRailsをLighttpdで動かす

研究室のWebサーバでは、80番ポートでApacheを走らせているのですが、RailsをApacheで動かすのって結構大変そうだったので、Apacheをプロキシ(mod_proxyが必要)として使って、Railsは別ポートのLighttpdで動かすようにしました。

さらに大学側の制限でサブドメインは使えないっぽいので、同一ドメインで複数のRailsアプリを動作させるようにも。

参考にしたのは
Jared's techno blog: How to use Apache2 as a proxy for lighttpd to handle multiple Ruby on Rail applications

Jared's techno blog: How to setup multiple apps on Ruby on Rails and Lighttpd

以前挑戦したときに失敗したのは、別ポートで同じアプリケーションが動作していて、アプリケーション側の設定変更が反映されていなかったためだったという..orz

とりあえずやったことをまとめておきます。

1. Lighttpdのインストール

wget http://www.lighttpd.net/download/lighttpd-1.4.12.tar.gz
tar zxvf lighttpd-1.4.12.tar.gz
cd lighttpd-1.4.12
./configure
make
make install

2. FastCGIのインストール

wget http://www.fastcgi.com/dist/fcgi.tar.gz
tar xvfz fcgi-2.4.0.tar.gz
cd fcgi-2.4.0
./configure
make
make install

3. FastCGI library for Rubyのインストール

gem install fcgi

4. Apache2の設定
mod_proxyを使うようにして、設定ファイル中に以下の記述を追加。

<IfModule mod_proxy.c>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass /application1/ http://127.0.0.1:3000/application1/
ProxyPass /application2/ http://127.0.0.1:3000/application2/
ProxyPassReverse / http://127.0.0.1:3000/
<IfModule mod_proxy.c>

5. Lighttpdの設定

server.port                = 3000
server.bind                = "localhost"
server.pid-file            = "/var/run/lighttpd.pid"
server.modules = ( "mod_setenv", "mod_rewrite", "mod_alias", "mod_redirect", "mod_access", "mod_fastcgi", "mod_accesslog")
server.document-root = "/path/to/lighttpd/document_root/"
 
# settings for application1
  $HTTP["url"] =~ "^/application1/" {
    server.document-root        = "/path/to/application1/public/"
    alias.url = ( "/application1/" => "/path/to/application1/public/" )
    server.indexfiles           = ( "index.html", "dispatch.fcgi")
    accesslog.filename          = "/path/to/application1/log/access.log"
    server.errorlog             = "/path/to/application1/log/server.log"
    server.error-handler-404 = "/dispatch.fcgi"
    url.rewrite             = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )
 
    ### fastcgi module
    ## read fastcgi.txt for more info
    fastcgi.server =  (
      "dispatch.fcgi" => (
         "localhost" => (
            "socket" => "/tmp/application1.fcgi.socket",
            "bin-path" => "/path/to/application1/public/dispatch.fcgi",
            "bin-environment" => (
                "RAILS_ENV" => "production"
                ),
            "idol-timeout" => 10,
            "check-local" => "disable",
            "min-procs" => 1,
            "max_procs" => 20
        )
      )
    )
  }
 
# settings for application2
  $HTTP["url"] =~ "^/application2/" {
    server.document-root        = "/path/to/application2/public/"
    alias.url = ( "/application2/" => "/path/to/application2/public/" )
    server.indexfiles           = ( "index.html" ,"dispatch.fcgi")
    accesslog.filename          = "/path/to/application2/log/access.log"
    server.errorlog             = "/path/to/application2/log/error.log"
    server.error-handler-404 = "dispatch.fcgi"
    url.rewrite              = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )
 
    ### fastcgi module
    ## read fastcgi.txt for more info
    fastcgi.server =  (
      "dispatch.fcgi" => (
         "localhost" => (
            "socket" => "/tmp/application2.fcgi.socket",
            "bin-path" => "/path/to/application2/public/dispatch.fcgi",
            "bin-environment" => ( "RAILS_ENV" => "production" ),
            "idol-timeout" => 10,
            "check-local" => "disable",
            "min-procs" => 1,
            "max_procs" => 5
        )
      )  
    )
  }
 
dir-listing.encoding = "utf-8"
dir-listing.activate         = "enable"
dir-listing.hide-dotfiles    = "enable"
 
### access module
url.access-deny             = ( "~", "RCS", "CVS", ".svn", ",v" )
 
### mod_setenv
$HTTP["url"] =~ "^/rss" {
  setenv.add-response-header = ("Content-Type" => "application/xml")
}
 
mimetype.assign             = (
 :
 :
)

6. Rails Application側の設定
application1, application2ともにconfig/routes.rbに

ActionController::Routing::Routes.draw do |map|
 ActionController::AbstractRequest.relative_url_root = "/application1" # これを追加!
 :
 :
 map.connect ':controller/:action/:id'
end
ActionController::Routing::Routes.draw do |map|
 ActionController::AbstractRequest.relative_url_root = "/application2" # これを追加!
 :
 :
 map.connect ':controller/:action/:id'
end

を追加。このとき必ずmap.connectより上に書くこと。
あとはApacheとLighttpdを再起動すればいいはず。

http://your.domain/application1/
http://your.domain/application2/

でそれぞれのアプリケーションにアクセスできるはずです。
それ以前にapplication1, application2を動かしていた場合は、必ずそれらをストップさせた後でApacheとLighttpdを起動すること。これ大事。

ちなみにPHPもLighttpdで動かしたいとかいう時は、ここが参考になるかと。
Kozupon.com - lighttpdで高速なhttpサーバを実現する!

1 comments in legacy system
2006年11月01日 yujis さん

トラックバックありがとうございます。
ドリコムでインターンされてるんですね。
前の会社のときはオフィスが近かったので、何度かお邪魔したことがありましたよ。

1 trackbacks in legacy system
2006年12月10日 DebianサーバにRails環境を構築する(1/2) 〜ruby/rubygem/railsのインストール〜 - 京の路

前も同じような記事を書いて来たのだが、今日もまた研究室のDebianサーバにRails環境を構築することにしたので、今回はブログを書きながら環境を構築して...