Mojoliciousをサブディレクトリで運用する

本番環境で複数のアプリケーションをデプロイするときには、サブドメイン運用ができるのであれば、リバースプロキシ + サブドメインでのデプロイをお勧めします。難しいことを考えないでも、サブドメインごとにバーチャルホストを設定してあげれば、アプリケーションの変更がいらないからです。

でもMojoliciousを使えばサブディレクトリで運用することも可能です。リバースプロキシ + サブディレクトリで運用する方法を紹介します。httpサーバーはApacheとします。

まずApacheの設定ファイルです。

  <VirtualHost *:80>
    ServerName perlcodesample.com
    <Proxy *>
      Order deny,allow
      Allow from all
    </Proxy>
    ProxyRequests Off
    ProxyPreserveHost On

    ProxyPass /app1 http://localhost:3000/app1 keepalive=On
    ProxyPassReverse /app1 http://localhost:3000/app1

    ProxyPass /app2 http://localhost:3001/app2 keepalive=On
    ProxyPassReverse /app2 http://localhost:3001/app2

    RequestHeader set X-ProxyPassReverse-UsePrefix "On"
    RequestHeader set X-Forwarded-HTTPS "0"
  </VirtualHost>

サブディレクトリごとにリバースプロキシの設定をしています。X-ProxyPassReverse-UsePrefixはアプリケーション独自のHTTPヘッダになります。

以下はアプリケーションです。before_dispatchを使って、URLの書き換えを行っています。これはMojoliciousのルーターやurl_forなどのメソッドが正しいURLを認識するために必要です。

use Mojolicious::Lite;

app->hook(before_dispatch => sub {
  my $self = shift;
  
  my $use_prefix
    = $self->req->headers->header('X-ProxyPassReverse-UsePrefix');
  
  if (defined $use_prefix && lc $use_prefix eq 'on') {
    my $prefix = shift @{$self->req->url->path->parts};
    $self->req->url->base->path->parse("/$prefix");
  }
});

get '/' => 'index';

get '/foo' => 'foo';

app->start;

__DATA__

@@ index.html.ep

URL: <a href="<%= url_for '/foo' %>">Foo</a>

@@ foo.html.ep

Foo

このようにアプリケーションを記述しておけば、サブディレクトリでの運用が可能になります。

関連情報