Catalyst::Manual::Deployment::Apache::mod_perl - Deploying Catalyst with mod_perl
-=head2 mod_perl Deployment
+=head1 mod_perl Deployment
mod_perl is not the best solution for many applications, but we'll list some
pros and cons so you can decide for yourself.
-=head3 Pros
+=head2 Pros
-=head4 Speed
+=head3 Speed
mod_perl is fast and your app will be loaded in memory
within each Apache process.
-=head4 Shared memory for multiple apps
+=head3 Shared memory for multiple apps
If you need to run several Catalyst apps on the same server, mod_perl will
share the memory for common modules.
-=head3 Cons
+=head2 Cons
-=head4 Memory usage
+=head3 Memory usage
Since your application is fully loaded in memory, every Apache process will
be rather large. This means a large Apache process will be tied up while
frontend server passing dynamic requests to a large backend mod_perl
server.
-=head4 Reloading
+=head3 Reloading
Any changes made to the core code of your app require a full Apache restart.
Catalyst does not support Apache::Reload or StatINC. This is another good
It is not possible to run two different versions of the same application in
the same Apache instance because the namespaces will collide.
-=head4 Cannot run different versions of libraries.
+=head3 Cannot run different versions of libraries.
If you have two different applications which run on the same machine,
which need two different versions of a library then the only way to do
This is entirely possible, but nullifies all the memory sharing benefits that
you get from having multiple applications sharing the same interpreter.
-=head4 Setup
+=head1 Setup
Now that we have that out of the way, let's talk about setting up mod_perl
to run a Catalyst app.
-=head4 1. Install Catalyst::Engine::Apache
-
-You should install the latest versions of both Catalyst and
-Catalyst::Engine::Apache. The Apache engines were separated from the
-Catalyst core in version 5.50 to allow for updates to the engine without
-requiring a new Catalyst release.
-
-=head4 2. Install Apache with mod_perl
+=head2 2. Install Apache with mod_perl
Both Apache 1.3 and Apache 2 are supported, although Apache 2 is highly
recommended. With Apache 2, make sure you are using the prefork MPM and not
apt-get install apache2-mpm-prefork
apt-get install libapache2-mod-perl2
-=head4 3. Configure your application
+=head2 3. Configure your application
Every Catalyst application will automagically become a mod_perl handler
when run within mod_perl. This makes the configuration extremely easy.
For an example Apache 1.3 configuration, please see the documentation for
L<Catalyst::Engine::Apache::MP13>.
-=head3 Test It
+=head2 Test It
That's it, your app is now a full-fledged mod_perl application! Try it out
by going to http://your.server.com/.
-=head3 Other Options
+=head1 Other Options
-=head4 Non-root location
+=head2 Non-root location
You may not always want to run your app at the root of your server or virtual
host. In this case, it's a simple change to run at any non-root location
When running this way, it is best to make use of the C<uri_for> method in
Catalyst for constructing correct links.
-=head4 Static file handling
+=head2 Static file handling
Static files can be served directly by Apache for a performance boost.
a two-tiered setup, the frontend server should handle static files.
The configuration to do this on the frontend will vary.
-The same is accomplished in lighttpd with the following snippet:
-
- $HTTP["url"] !~ "^/(?:img/|static/|css/|favicon.ico$)" {
- fastcgi.server = (
- "" => (
- "MyApp" => (
- "socket" => "/tmp/myapp.socket",
- "check-local" => "disable",
- )
- )
- )
- }
-
-Which serves everything in the img, static, css directories
-statically, as well as the favicon file.
-
Note the path of the application needs to be stated explicitly in the
-web server configuration for both these recipes.
-
-=head2 Catalyst on shared hosting
-
-So, you want to put your Catalyst app out there for the whole world to
-see, but you don't want to break the bank. There is an answer - if you
-can get shared hosting with FastCGI and a shell, you can install your
-Catalyst app in a local directory on your shared host. First, run
-
- perl -MCPAN -e shell
-
-and go through the standard CPAN configuration process. Then exit out
-without installing anything. Next, open your .bashrc and add
-
- export PATH=$HOME/local/bin:$HOME/local/script:$PATH
- perlversion=`perl -v | grep 'built for' | awk '{print $4}' | sed -e 's/v//;'`
- export PERL5LIB=$HOME/local/share/perl/$perlversion:$HOME/local/lib/perl/$perlversion:$HOME/local/lib:$PERL5LIB
-
-and log out, then back in again (or run C<". .bashrc"> if you
-prefer). Finally, edit C<.cpan/CPAN/MyConfig.pm> and add
-
- 'make_install_arg' => qq[SITEPREFIX=$ENV{HOME}/local],
- 'makepl_arg' => qq[INSTALLDIRS=site install_base=$ENV{HOME}/local],
-
-Now you can install the modules you need using CPAN as normal; they
-will be installed into your local directory, and perl will pick them
-up. Finally, change directory into the root of your virtual host and
-symlink your application's script directory in:
-
- cd path/to/mydomain.com
- ln -s ~/lib/MyApp/script script
-
-And add the following lines to your .htaccess file (assuming the server
-is setup to handle .pl as fcgi - you may need to rename the script to
-myapp_fastcgi.fcgi and/or use a SetHandler directive):
-
- RewriteEngine On
- RewriteCond %{REQUEST_URI} !^/?script/myapp_fastcgi.pl
- RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L]
-
-Now C<http://mydomain.com/> should now Just Work. Congratulations, now
-you can tell your friends about your new website (or in our case, tell
-the client it's time to pay the invoice :) )
-
-=head2 FastCGI Deployment
-
-FastCGI is a high-performance extension to CGI. It is suitable
-for production environments.
-
-=head3 Pros
-
-=head4 Speed
-
-FastCGI performs equally as well as mod_perl. Don't let the 'CGI' fool you;
-your app runs as multiple persistent processes ready to receive connections
-from the web server.
-
-=head4 App Server
-
-When using external FastCGI servers, your application runs as a standalone
-application server. It may be restarted independently from the web server.
-This allows for a more robust environment and faster reload times when
-pushing new app changes. The frontend server can even be configured to
-display a friendly "down for maintenance" page while the application is
-restarting.
-
-=head4 Load-balancing
-
-You can launch your application on multiple backend servers and allow the
-frontend web server to load-balance between all of them. And of course, if
-one goes down, your app continues to run fine.
-
-=head4 Multiple versions of the same app
-
-Each FastCGI application is a separate process, so you can run different
-versions of the same app on a single server.
-
-=head4 Can run with threaded Apache
-
-Since your app is not running inside of Apache, the faster mpm_worker module
-can be used without worrying about the thread safety of your application.
-
-=head3 Cons
-
-You may have to disable mod_deflate. If you experience page hangs with
-mod_fastcgi then remove deflate.load and deflate.conf from mods-enabled/
-
-=head4 More complex environment
-
-With FastCGI, there are more things to monitor and more processes running
-than when using mod_perl.
-
-=head3 Setup
-
-=head4 1. Install Apache with mod_fastcgi
-
-mod_fastcgi for Apache is a third party module, and can be found at
-L<http://www.fastcgi.com/>. It is also packaged in many distributions,
-for example, libapache2-mod-fastcgi in Debian. You will also need to install
-the L<FCGI> module from cpan.
-
-Important Note! If you experience difficulty properly rendering pages,
-try disabling Apache's mod_deflate (Deflate Module), e.g. 'a2dismod deflate'.
-
-=head4 2. Configure your application
-
- # Serve static content directly
- DocumentRoot /var/www/MyApp/root
- Alias /static /var/www/MyApp/root/static
-
- FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -processes 3
- Alias /myapp/ /var/www/MyApp/script/myapp_fastcgi.pl/
-
- # Or, run at the root
- Alias / /var/www/MyApp/script/myapp_fastcgi.pl/
-
-The above commands will launch 3 app processes and make the app available at
-/myapp/
-
-=head3 Standalone server mode
-
-While not as easy as the previous method, running your app as an external
-server gives you much more flexibility.
-
-First, launch your app as a standalone server listening on a socket.
-
- script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 -p /tmp/myapp.pid -d
-
-You can also listen on a TCP port if your web server is not on the same
-machine.
-
- script/myapp_fastcgi.pl -l :8080 -n 5 -p /tmp/myapp.pid -d
-
-You will probably want to write an init script to handle starting/stopping
-of the app using the pid file.
-
-Now, we simply configure Apache to connect to the running server.
-
- # 502 is a Bad Gateway error, and will occur if the backend server is down
- # This allows us to display a friendly static page that says "down for
- # maintenance"
- Alias /_errors /var/www/MyApp/root/error-pages
- ErrorDocument 502 /_errors/502.html
-
- FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket
- Alias /myapp/ /tmp/myapp.fcgi/
-
- # Or, run at the root
- Alias / /tmp/myapp.fcgi/
-
-=head3 More Info
-
-L<Catalyst::Engine::FastCGI>.
-
-=head2 Development server deployment
-
-The development server is a mini web server written in perl. If you
-expect a low number of hits or you don't need mod_perl/FastCGI speed,
-you could use the development server as the application server with a
-lightweight proxy web server at the front. However, consider using
-L<Catalyst::Engine::HTTP::Prefork> for this kind of deployment instead, since
-it can better handle multiple concurrent requests without forking, or can
-prefork a set number of servers for improved performance.
-
-=head3 Pros
-
-As this is an application server setup, the pros are the same as
-FastCGI (with the exception of speed).
-It is also:
-
-=head4 Simple
-
-The development server is what you create your code on, so if it works
-here, it should work in production!
-
-=head3 Cons
-
-=head4 Speed
-
-Not as fast as mod_perl or FastCGI. Needs to fork for each request
-that comes in - make sure static files are served by the web server to
-save forking.
-
-=head3 Setup
-
-=head4 Start up the development server
-
- script/myapp_server.pl -p 8080 -k -f -pidfile=/tmp/myapp.pid
-
-You will probably want to write an init script to handle stop/starting
-the app using the pid file.
-
-=head4 Configuring Apache
-
-Make sure mod_proxy is enabled and add:
-
- # Serve static content directly
- DocumentRoot /var/www/MyApp/root
- Alias /static /var/www/MyApp/root/static
-
- ProxyRequests Off
- <Proxy *>
- Order deny,allow
- Allow from all
- </Proxy>
-
- # Need to specifically stop these paths from being passed to proxy
- ProxyPass /static !
- ProxyPass /favicon.ico !
-
- ProxyPass / http://localhost:8080/
- ProxyPassReverse / http://localhost:8080/
-
- # This is optional if you'd like to show a custom error page
- # if the proxy is not available
- ErrorDocument 502 /static/error_pages/http502.html
-
-You can wrap the above within a VirtualHost container if you want
-different apps served on the same host.
-
- # Set up your Catalyst app as a mod_perl 2.x application in httpd.conf
- PerlSwitches -I/var/www/MyApp/lib
-
- # Preload your entire application
- PerlModule MyApp
-
- <VirtualHost *>
- ServerName myapp.hostname.com
- DocumentRoot /var/www/MyApp/root
-
- <Location />
- SetHandler modperl
- PerlResponseHandler MyApp
- </Location>
-
- # you can also run your app in any non-root location
- <Location /some/other/path>
- SetHandler perl-script
- PerlResponseHandler MyApp
- </Location>
-
- # Make sure to let Apache handle your static files
- # (It is not necessary to remove the Static::Simple plugin
- # in production; Apache will bypass Static::Simple if
- # configured in this way)
-
- <Location /static>
- SetHandler default-handler
- </Location>
-
- # If not running at a root location in a VirtualHost,
- # you'll probably need to set an Alias to the location
- # of your static files, and allow access to this location:
-
- Alias /myapp/static /filesystem/path/to/MyApp/root/static
- <Directory /filesystem/path/to/MyApp/root/static>
- allow from all
- </Directory>
- <Location /myapp/static>
- SetHandler default-handler
- </Location>
-
- </VirtualHost>
-
-=head1 DESCRIPTION
-
-This is the Catalyst engine specialized for Apache2 mod_perl version 2.x.
-
-=head1 ModPerl::Registry
-
-While this method is not recommended, you can also run your Catalyst
-application via a ModPerl::Registry script.
-
-httpd.conf:
-
- PerlModule ModPerl::Registry
- Alias / /var/www/MyApp/script/myapp_registry.pl/
-
- <Directory /var/www/MyApp/script>
- Options +ExecCGI
- </Directory>
-
- <Location />
- SetHandler perl-script
- PerlResponseHandler ModPerl::Registry
- </Location>
-
-script/myapp_registry.pl (you will need to create this):
-
- #!/usr/bin/perl
-
- use strict;
- use warnings;
- use MyApp;
-
- MyApp->handle_request( Apache2::RequestUtil->request );
-
+web server configuration for this recipes.
=head1 AUTHORS