bc-bd.org

Not a blog

Mojolicious Behind Apache With Mod_proxy

This is the only way I got an Mojolicious application to work behind an apache2 web server using mod_proxy.

Setting the base will make sure that your routes match the incoming URLs and that the right URL is used in redirects:

my $base = 'http://localhost:3000/app1';

hook 'before_dispatch' => sub {
        shift->req->url->base(Mojo::URL->new($base));
};

When using the style sheet or JavaScript helper a leading slash is important, else the path will be wrong:

%= stylesheet '/css/foo.css'

And this is the apache config snippet:

ProxyPass /app1 http://localhost:3000
ProxyPassReverse /app1 http://localhost:3000/app1

Note the missing /app1 at the end of the ProxyPass line.

The complete Mojolicious code:

#!/usr/bin/env perl
use Mojolicious::Lite;

use Time::HiRes qw/gettimeofday/;

my $base = 'http://localhost:3000/app1';

hook 'before_dispatch' => sub {
        shift->req->url->base(Mojo::URL->new($base));
};

under sub {
        shift->stash(now => join('.', gettimeofday()));
};

get '/' => sub {
        my $self = shift;
        $self->render('index');
} => 'index';

get '/foo' => sub {
        my $self = shift;
        $self->render('foo');
};

get '/redirect' => sub {
        my $self = shift;
        $self->redirect_to('foo');
};
 app->start;

__DATA__

@@ foo.html.ep
% layout 'default';
% title 'Foo';

@@ index.html.ep
% layout 'default';
% title 'index';

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
  <head>
    %= stylesheet '/css/foo.css'
    <title><%= title %></title>
  </head>
  <body>
    <h1>Welcome to <%= title %></h1>
    <p>Now: <%= stash('now') %></p>
    <%= content %>
    <hr/>
    <ul>
     <li><%= link_to 'Index' => 'index' %></li>
     <li><%= link_to 'Foo' => 'foo' %></li>
     <li><%= link_to 'Redirect' => 'redirect' %>: Will redirect to foo</li>
    </ul>
  </body>
</html>