単一のCatalyst(PSGI) + Nginxで複数のサブドメインを運用してみる。

これCatalyst(FCGI)+Apache時代にもやってたんだけど、普通はどんな感じなんだろ。
やっぱサブドメイン毎にCatalystを分けるのかな?
ちなみに、Catalyst(FCGI)+Apache版は -> この辺参照

やりたい事としては、

MyApp::Controller::Milk->index()
MyApp::Controller::Coffee->index()

を、それぞれ、

http://milk.example.com/
http://coffee.example.com/

って感じでアクセスしたいんですが。

最初から分ければ、

catalyst.pl Milk
catalyst.pl Coffee

Milk::Controller::Root->index()
Coffee::Controller::Root->index()

って、2つ作って、それぞれnginxにproxy_passを設定すればいいんですが・・。

nginxにapacheで言うところのSetenv的な動きをする設定がわからなかったんですが、
(ちなみにadd_headerは、リクエストヘッダではなく、レスポンスヘッダなので注意w)
NginxHttpHeadersMoreModuleってモジュール入れたらできるようです。
(Nginxのリビルド必須です)

で、簡単にやる方法として、
「X-Forwarded-Host」とかは、普通に

proxy_set_header X-Forwarded-Host milk

で、上書きできるのでこれでいいかなー。どうせ使ってないし。(使ってました。追記参照↓)

Catalystで受け取る時は、

$c->engine->env->{'HTTP_HOST'}; # milk
$c->engine->env->{'HTTP_X_FORWARDED_HOST'}; # milk

で取得できます。

今回もMyApp.pmのprepare_actionを弄る事にします。

sub prepare_action {
    my $c = shift;

    if ( $c->req->{'_path'} ) {
        $c->req->{'_path'} = $c->engine->env->{'HTTP_HOST'} . '/' . $c->req->{'_path'};
    }
    else {
        $c->req->{'_path'} = $c->engine->env->{'HTTP_HOST'};
    }

    $c->dispatcher->prepare_action( $c, @_ );
}

こんなのを__PACKAGE__->setup();の下あたりに追加。

Nginxは上にも書いたけど、

server {
    listen 80;
    server_name milk.example.com;

    location ~ . {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Forwarded-Host milk;
        break;
    }
}

これで、8080で待っている.psgiに向けてプロキシ。
↑のNginxの設定だけだと静的ファイルまでくるので、適時修正。

(追記)
Catalystの$c->uri_forで、HTTP_HOST使ってるみたいですね。
やっぱNginxHttpHeadersMoreModule使う方が無難か。