mod_proxyによるApacheとGrailsのお手軽連携

Grailsで作ったアプリは簡単にwarにしてTomcatとかにデプロイできます。
ですが、warのデプロイの手間もなんだか面倒だし、

$ grails run-app

とdevelopmentモードで起動しておくと、ホットデプロイによるカスタマイズもできて結構便利だし、趣味アプリならもうこれでええんちゃうかと。

この場合Grailsに組み込まれてるJettyが使われます。

デフォルトでは8080ポートですが、

$ grails -Dserver.port=4649 run-app

とポート番号も指定できます。


で、このサービスをユーザに使ってねーと公開するときですが、やっぱり80ポートじゃないとURLが汚くてあんまりうれしくないわけです。

$ grails -Dserver.port=80 run-app

としてもいいですけど、すでにApacheが動いてる場合にはバッティングしてしまいますね。


そこで、mod_proxyの出番です。
http://httpd.apache.org/docs/2.2/ja/mod/mod_proxy.html


Apache2で、mod_proxyをいれて、以下のようにかけば、内部の別ポート番号で起動してるWebアプリと簡単に連携できます。

ProxyPass /hoge http://localhost:8080/hoge
ProxyPassReverse /hoge http://localhost:8080/hoge


Tomcatならmod_proxy_ajpを使ってAJPプロトコル連携も簡単にできます(http://xxxx:8080/hoge のかわりに、ajp://xxxx:8009/hoge とかかくだけ)。
でも、JettyとAJP通信する方法がわからないし(あまり調べてない)、趣味アプリ程度ならとりあえずmod_proxyで十分だろうと。


ProxyPassは、クライアント→サーバ向きの連携を実現する設定。
でも、これだけだと、サーバからリダイレクトすると素のhttp://localhost:8080/hogeになってしまいます。

そこで、ProxyPassReverse。
これを追加しておけばリバースプロキシとして動作するので、リダイレクトされても平気。


あと、超重要事項ですが、Proxy"Path"ではないです。
PathではなくてPassです。プロキシにパスするぜ!という意味でProxyPassです。
Pathじゃなくて、ProxyPassです。
大事なことなので2回書きました。

起動コマンドがスペルミスかもよ?といっていたら、素直にスペルミスを疑いましょう。


いや、おれはスペルミスなんかしない。
LoadModuleで本当にロードされてないんじゃね?という責任転嫁傾向の方は、

 $ apachectrl -M
 (環境によっては、apache2ctrlの場合もある)

とすると、今ロードされてるモジュールの一覧と、conf系のシンタックスチェック結果が表示されるので、これで確認しましょう。

Invalid command 'ProxyPath', perhaps misspelled or defined by a module not included in the server configuration

スペルミスですた。ハイ。*1

2/16追記

Ubuntuサーバでやったんですが、あともう一つ落とし穴があって、

 client denied by server configuration: proxy:http://localhost:8080/hoge

というエラーが出てしまう場合があります。


原因は↓これでした。

あぁ、そうだ。(Debian の?) Apache2 のデフォルトは、proxy の利用がオフになってるんだった。インスコすると、サーバ類は勝手に起動するのに、ここは使えない設定だなんて。Debian はいらない子><
ヽ( ・∀・)ノくまくまー(2007-10-08)

/etc/apache2/mods-enabled/proxy.conf にAllowを追加したら無事に開通しました。ふう。

*1:いや、マジで何回見直しても気づかんかったんよ...orz