読者です 読者をやめる 読者になる 読者になる

mod_passengerでWSGIアプリケーションを動かす

Ruby Python Django

Passenger(mod_passenger)は言わずと知れたRuby on Rails/Rackアプリケーションを動かすための定番サーバーのひとつ。

実はPassengerではPython WSGIを動かすこともできる。誰が得するか分からないから誰もほとんど言及していないけど。

本番環境でPassengerを使ってWSGIアプリケーションを動かそうとは思わないけど、virtualenvとの親和性が高い、複数のバージョンのPythonを使って開発ができるというメリットもあるから、開発環境では使ってみてもいいかもしれない。

あと、すでにmod_passengerの環境が構築済みならば、Trac等の定番アプリケーションを動かす場合でも、mod_wsgiFastCGIよりも設定が楽な気がする。まあ、こういったケースではRedmine等を使うでしょうが・・・

WSGIを動かすにあたっては以下のページを参考にした。

「PassengerでTrac」という日本語エントリを書かれている方もいたので、こちらも役に立つかも。

httpdの設定

Passengerをインストールした時に示される、

# /etc/httpd/conf.d/passenger.conf
LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.5/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.5
PassengerRuby /usr/local/bin/ruby

のような設定が済んでいるならば、

<VirtualHost *:80>
  ServerName   wsgi.example.com
  DocumentRoot /var/www/virtual/wsgi.example.com/public
</VirtualHost>

のようなVirtualHostの設定を加えるだけで、DocumentRootの一つ上のディレクトリ、この場合は/var/www/virtual/wsgi.example.comに配置したWSGIアプリケーションを実行することができる。

WSGIの設定

重要なのはDocumentRootとpassenger_wsgi.pyという起動スクリプトとの位置関係で、passenger_wsgi.pyをDocumentRootの一つ上の階層におかなくてはならない。

典型的なDjangoアプリケーション(myproject)の場合、次のような配置になるだろう。

- /var/www/virtual/wsgi.example.com
-- passenger_wsgi.py
-- public
--- images
--- css
-- tmp
--- restart.txt
-- myproject
--- __init__.py
--- settings.py
--- urls.py
--- manage.py
--- myapp

詳細はPassengerドキュメントのApplication Rootの項を参照のこと。

Djangoを動かす場合には、passenger_wsgi.pyの中身は次のようになる。

# -*- mode: Python; -*-
import sys
import os

INTERP = "/path/to/virtualenv/wsgi.example.com"
if sys.executable != INTERP:
    os.execl(INTERP, INTERP, *sys.argv)

path = '/var/www/virtual/wsgi.example.com'
if path not in sys.path:
   sys.path.insert(0, path)

os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'

from django.core.handlers import wsgi
application = wsgi.WSGIHandler()

INTERPが含まれる3行は、

$ virtualenv.py --python=/usr/bin/python2.5 --no-site-packages /path/to/virtualenv/wsgi.example.com

のようなコマンドで作ったvirtualenv環境を想定している。OS標準のPythonを使う場合には省略しても可。

WSGIプロセスを再起動する

WSGIプロセスを再起動するには、

  • httpdを再起動する
  • tmp/restart.txtのタイムスタンプを更新する

の二つの方法がある。Passengerを開発サーバーとして利用するならば、特定ディレクトリ以下のファイルが更新されたら自動的にtmp/restart.txtも更新するスクリプトを用意しておく必要があるだろう。

WSGIプロセスのプロセス数の設定

まさか実稼働環境でPassenger+WSGIを使わないだろうから標準の設定で十分だと思うが、Passengerのプロセス数の設定を行えば、WSGI子プロセス数の最大値等を設定できる。

でも、Passenger+WSGIはシングルスレッド・シングルプロセスだから、これらの値をいじろうと考えるくらいならば、素直にmod_wsgiFastCGIを使った方がいいと思うな・・・