リバースプロキシ経由でDancerを動かす方法
VPSなどで同一ホストに複数のWebアプリをデプロイしたいとき、ドメインは同じでサブディレクトリ毎にアプリのルートを割り当てるということをよくやると思う。PHPやmod_perl等を使ってApacheの中で動かすことも一般的だが、最近はapacheまたはnginxなどの高速なWebサーバをリバースプロキシとして動かし、本体の処理はローカルでマルチコアを上手く使いこなすWebコンテナ(そういうのをプリフォークサーバと呼ぶらしい)でさばくというのが流行らしい。
それをPerlの軽量WAFであるDancerでやったのでメモ。
Apacheの設定
例えばhttp://xx.xx.xx.xx/foo/barをアプリのルートにしたい場合、HTTPリクエストヘッダのX-Request-Hostにxx.xx.xx.xx、
request-baseに/foo/barが入ってることをDancerのリバースプロキシ用プラグイン(Dancer::Plugin::ProxyPass)は要求する。
X-Request-Hostはmod_proxyがつけてくれるっぽいがrequest-baseのほうはつけてくれないのでmod_headersを使って自分で追加する。ローカルで動く本体のサーバのポートが5000の場合は以下のようになる。(allow from allのところは必要に応じて変えてください)
Order deny,allow allow from all RequestHeader set request-base /foo/bar ProxyPass http://localhost:5000 ProxyPassReverse http://localhost:5000
proxy_httpとheadersをa2enmodしてなければして、apacheを再起動
# a2enmod proxy_http headers # service apache2 restart
Dancer側での扱い
Dancer::Plugin::ProxyPassではproxy->uri_for()というメソッドがあり、TemplateToolkitの中でも[% proxy.uri_for('subdir') %]という感じで使うことができる。このメソッドはリバースプロキシ経由でない時(ヘッダに項目がないとき)は通常のパス指定にフォールバックするので、そのままスタンドアロンでも動かせる。
なので以下でproxy.uri_forを使うように書き換える。
- コントローラ(lib/$YourDancerApp/App.pm)の中でredirectするところ
- viewのテンプレートファイルの中の以下のようなタグで相対パスを指定するところ
- script src="xxx"
- link href="xxx"
- a href="xxx"
- img src="xxx"
- form action="xxx"
- などなど
例えば(TTを使ってる場合)
# layout/main.tt (中略) <link rel="stylesheet" href="[% proxy.uri_for('/') %]css/style.css" /> (中略) <script src="[% proxy.uri_for('/') %]javascript/jquery.js" /> (略)
# lib/YourDancerApp/App.pm (中略) use Dancer::Plugin::ProxyPath; (中略) get '/hoge' => { redirect proxy->uri_for('/'); }; (中略)
などとする。
ローカル側の本体サーバ
Plackupを起動するところは通常と同じ。
# cd $YourDancerAppDir # nohup plackup bin/app.pl &
というわけで
Dancerは便利です。