Catalyst Advent - Day 7 - mod_perl Deployment
NOTE: This article was written in 2005. For more up-to-date information on deplyoment, please see http://dev.catalyst.perl.org/wiki/deployment
In today's entry, I'll be talking about deploying an application in production using Apache and mod_perl.
Pros & Cons
mod_perl is the best solution for many applications, but I'll list some pros and cons so you can decide for yourself. The other production deployment option is FastCGI, which I'll talk about in a future calendar article.
Pros
Speed
mod_perl is very fast and your app will benefit from being loaded in memory within each Apache process.
Shared memory for multiple apps
Cons
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 serving static files, large files, or dealing with slow clients. For this reason, it is best to run a two-tiered web architecture with a lightweight frontend server passing dynamic requests to a large backend mod_perl server.
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
reason to run a frontend web server where you can set up an
ErrorDocument 502
page to report that your app is down for maintenance.
Cannot run multiple versions of the same app
It is not possible to run two different versions of the same application in the same Apache instance because the namespaces will collide.
Setup
Now that we have that out of the way, let's talk about setting up mod_perl to run a Catalyst app.
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.
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 the worker MPM. The reason for this is that many Perl modules are not thread-safe and may have problems running within the threaded worker environment. Catalyst is thread-safe however, so if you know what you're doing, you may be able to run using worker.
In Debian, the following commands should get you going.
apt-get install apache2-mpm-prefork apt-get install libapache2-mod-perl2
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. Here is a basic Apache 2 configuration.
PerlSwitches -I/var/www/MyApp/lib PerlModule MyApp <Location /> SetHandler modperl PerlResponseHandler MyApp </Location>
The most important line here is PerlModule MyApp
. This causes mod_perl
to preload your entire application into shared memory, including all of your
controller, model, and view classes and configuration. If you have -Debug
mode enabled, you will see the startup output scroll by when you first
start Apache.
For an example Apache 1.3 configuration, please see the documentation for Catalyst::Engine::Apache::MP13 [1].
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/.
Other Options
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 of your choice.
<Location /myapp> SetHandler modperl PerlResponseHandler MyApp </Location>
When running this way, it is best to make use of the uri_for
method in
Catalyst for constructing correct links.
Static file handling
Static files can be served directly by Apache for a performance boost.
DocumentRoot /var/www/MyApp/root <Location /static> SetHandler default-handler </Location>
This will let all files within root/static be handled directly by Apache. In a two-tiered setup, the frontend server should handle static files. The configuration to do this on the frontend will vary.
--Andy Grundman