2008年07月14日
PasteDeployを使って複数のWSGIアプリを一つのプロセスに共存させる
社内でWebアプリをデモしたいとか、開発環境としてLinuxサーバーが欲しくなったとき、「サーバー欲しい」と言えば すぐにLinuxの入った仮想環境をもらうことができます。
せっかくもらったrootを持ってるサーバーなので、MercurialやTracなど入れて遊んでいるのですが、 PCサーバー上の仮想マシンなので、メモリが何GBも載っている訳ではありません。 すこしメモリ使用量を削減してみることにしました。
いまどきのPython製Webアプリは、大抵WSGIという標準インタフェースを持っているので、 PasteDeploy(Pylonsが利用しているWSGIアプリ用のメタフレームワーク)を利用して、 一つのPythonプロセスに複数のWSGIアプリを同居させてみます。
PasteDeploy設定ファイル
Pylonsアプリの設定ファイルを流用して、複数のアプリをcompositeするように設定します。# comp_exam.ini # ...省略... [composite:main] use = egg:Paste#urlmap /trac = tracapp /hg = hgapp /nanika = nanika ## factoryについては後述 [app:tracapp] paste.app_factory = compapp:trac_factory trac.env_parent_dir = /path/to/trac [app:hgapp] paste.app_factory = compapp:hg_factory hgapp.rep_path = /path/to/hg/repo ## もとのPylonsアプリを、[app:main]から[app:適当な名前]に変更します。 [app:nanika] use = egg:Nanika lang = ja # ...省略...
WSGIアプリケーションファクトリ
PasteDeployにWSGIアプリを渡すために、WSGIアプリのファクトリを作ります。このファクトリは、 引数にconfig(設定ファイルの内容)を受け取って、WSGIアプリのオブジェクトを返します。 上の設定ファイルに対応するcompapp.pyは以下の用になります。
#compapp.py import mercurial.hgweb.hgweb_mod as hgweb import trac.web.main as tracweb def hg_factory(config, **localconfig): return hgweb.hgweb(localconfig['hgapp.rep_path']) def trac_factory(config, **localconfig): def trac_app(environ, start_response): environ['trac.env_parent_dir'] = localconfig['trac.env_parent_dir'] return tracweb.dispatch_request(environ, start_response) return trac_appこのファイルをPYTHONPATHが通ったところにおいて、通常のPylonsアプリを起動するのと 同じ感覚で起動します。
$ PYTHONPATH=. paster serve comp_exam.ini
これで、http://localhost/trac/ で Trac に、 http://localhost/hg/ で Mercurial にアクセスできるようになります。
追記: TracとPythonの最適化オプションについて
Trac-0.11が出たので入れてみたのですが、PYTHONOPTIMIZE=xという環境変数をセットしてPythonの最適化を有効にすると、Wikiのヘッダとフッタが出なかったりしてハマりました。Pythonの最適化オプションってあまり使われていないかもしれませんが、僕のように貧乏性な方はお気をつけください。
@methane