-
Notifications
You must be signed in to change notification settings - Fork 580
Apache deployment
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>
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.
you can also do the following way using path.
<VirtualHost *:80> ServerName somehost.com <Proxy *> Order deny,allow Allow from all 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-Forwarded-HTTPS "0"
If X-Forwarded-Host
exists, url_for
and redirect_to
method can write absolute URL right. 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 = shift @{$self->req->url->path->parts};
push @{$self->req->url->base->path->parts}, $path;
}
});
<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>
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.
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/}));
});
}
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 myapp.local
DocumentRoot /home/sri/myapp
PerlOptions +Parent
<Perl>
$ENV{PLACK_ENV} = 'production';
$ENV{MOJO_HOME} = '/home/sri/myapp';
$ENV{MOJO_MODE} = 'deployment';
</Perl>
<Location />
SetHandler modperl
PerlResponseHandler Plack::Handler::Apache2
PerlSetVar psgi_app /home/sri/myapp/script/myapp
</Location>
</VirtualHost>
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