Skip to content
Yuki Kimoto edited this page Jun 11, 2013 · 34 revisions

Apache deployment

Apache/mod_proxy Preamble

It is important for you to note that the Apache2 modules mod_proxy and mod_proxy_http must be enabled.

LoadModule proxy_module lib/httpd/mod_proxy.so
LoadModule proxy_http_module lib/httpd/mod_proxy_http.so

It is also important to set permissions for proxying for security purposes, below is an example.

<Proxy *>
  Order allow,deny
  Allow from all
</Proxy>

Apache/mod_proxy (Host name)

If you want to deploy multiple applications, it is easy to use virtual-host and mod_proxy in Apache.

<VirtualHost *:80>

   ServerName app1.somehost.com
   ProxyPass / http://localhost:3000/
   ProxyPassReverse / http://localhost:3000/

    </VirtualHost>

    <VirtualHost *:80>

   ServerName app2.somehost.com
   ProxyPass / http://localhost:3001/
   ProxyPassReverse / http://localhost:3001/

    </VirtualHost>

Note that you must create subdomains for each applications in above way. and set MOJO_REVERSE_PROXY environment variable to 1, redirect_to method can write absolute URL right.

# Application Class
sub startup {
    my $self = shift;
    $ENV{MOJO_REVERSE_PROXY} = 1;
}

If you see apache "Service Temporarily Unavailable" error, SELinux mode is maybe set to "enforcing". This usually happens on Red Hat based Linux distributions. SELinux forbids the Apache webserver to connect to the network. There is a certain boolean variable which be set. Please run the following command to allow the Apache webserver to connect to network (even it's on the localhost).

$ sudo setsebool -P httpd_can_network_connect=1

Please note: There is no need to turn off SELinux completely.

Apache/mod_proxy (Path)

you can also do the following way using path.

<VirtualHost *:80>

   ServerName somehost.com
   <Proxy *>
     Order deny,allow
     Allow from all
   </Proxy>
   ProxyRequests Off
   ProxyPreserveHost On

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

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

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

and set MOJO_REVERSE_PROXY environment variable to 1, redirect_to method can write absolute URL right.

# Application Class
sub startup {
    my $self = shift;
    $ENV{MOJO_REVERSE_PROXY} = 1;
}

In this case not like using host name, you must set request base URL path by yourself.

app->hook('before_dispatch' => sub {
    my $self = shift;
    
    if ($self->req->headers->header('X-Forwarded-Host')) {
        ### Proxy Path setting ###
        my $path = '/app1';
        
        $self->req->url->base->path->parse($path);
    }
});

Apache/mod_proxy (Serving static files)

<VirtualHost *:80>

  ServerName app.somehost.com

  # Make sure that document root points to public dir of our application
  DocumentRoot /path/to/public

  # Don't proxy any request beginning with the keyword "/static".
  # So, for example, "/static/logo.gif" will be served directly by
  # Apache from the "/path/to/public/static/logo.gif file"
  # The ! (exclamation mark) keyword in ProxyPass means "don't"
  ProxyPass /static !

  # Another one for "favicon.ico", so that explorer and mozilla are happy
  ProxyPass /favicon.ico !

  # And now we send back to our application everyting else that does
  # not begin with "/static" or "/favicon.ico"
  ProxyPass / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/

</VirtualHost>

Apache/CGI

To make Mojolicious application run in CGI mode under Apache make sure your httpd.conf or .htaccess file looks like following:

AddHandler cgi-script .cgi
Options +ExecCGI

IndexIgnore *

RewriteEngine on

RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} -f
RewriteRule ^(.*) public/$1 [L]

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-f
RewriteRule ^(.*) myapp.cgi [L] 

In this way you make Apache render static files from /public folder for you.

Pretty "Web 2.0" URLs

Nobody really likes URLs like www.mycompany.com/myapp.cgi/foo/bar. Instead we want prefer seeing: www.mycompany.com/foo/bar, they are much nicer to use. The following configuration will hide the fact that the application is running from a cgi. Particularly useful if your hosting environment forbids the use of ScriptAlias.

## .htaccess
RewriteEngine on
# Rewrite only if the request isn't for a real file, directory, or symlink.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ myapp.cgi/$1 [L]

## lib/MyApp.pm
sub startup {
     my $self = shift;
     # ... your start up and routes.
     $self->hook( before_dispatch => sub {
          my $self = shift;
          # notice: url must be fully-qualified or absolute, ending in '/' matters.
          $self->req->url->base(Mojo::URL->new(q{http://www.mycompany.com/}));
     });
}

Apache/mod_perl (PSGI/Plack)

mod_perl is a good example for a PSGI adapter that is used without plackup, note that setting the PLACK_ENV environment variable is required for Mojolicious PSGI detection.

In shared environments with more than one VirtualHost using mod_perl PerlOptions +Parent is recommended. Otherwise there can be namespace conflicts.

<VirtualHost *:80>
  ServerName localhost
  DocumentRoot /home/sri/myapp/public

  PerlOptions +Parent

  <Perl>
    $ENV{PLACK_ENV} = 'production';
    $ENV{MOJO_HOME} = '/home/sri/myapp';
    $ENV{MOJO_MODE} = 'deployment';
  </Perl>

  <Location /myapp>
    SetHandler perl-script
    PerlResponseHandler Plack::Handler::Apache2
    PerlSetVar psgi_app /home/sri/myapp/script/myapp
  </Location>
</VirtualHost>

Apache/Shared Hosting

We have a discussion on the mailinglist about setting up mojo in shared environments.

https://groups.google.com/group/mojolicious/browse_thread/thread/6f17653fe30ab884

And here is the actual example working equally well with mod_fastcgi and mod_cgi: http://github.com/kberov/MYDLjE/blob/master/.htaccess

Clone this wiki locally