3 Catalyst::Manual::Deployment::Apache::mod_perl - Deploying Catalyst with mod_perl
5 =head2 mod_perl Deployment
7 mod_perl is not the best solution for many applications, but we'll list some
8 pros and cons so you can decide for yourself.
14 mod_perl is fast and your app will be loaded in memory
15 within each Apache process.
17 =head4 Shared memory for multiple apps
19 If you need to run several Catalyst apps on the same server, mod_perl will
20 share the memory for common modules.
26 Since your application is fully loaded in memory, every Apache process will
27 be rather large. This means a large Apache process will be tied up while
28 serving static files, large files, or dealing with slow clients. For this
29 reason, it is best to run a two-tiered web architecture with a lightweight
30 frontend server passing dynamic requests to a large backend mod_perl
35 Any changes made to the core code of your app require a full Apache restart.
36 Catalyst does not support Apache::Reload or StatINC. This is another good
37 reason to run a frontend web server where you can set up an
38 C<ErrorDocument 502> page to report that your app is down for maintenance.
40 =head4 Cannot run multiple versions of the same app
42 It is not possible to run two different versions of the same application in
43 the same Apache instance because the namespaces will collide.
45 =head4 Cannot run different versions of libraries.
47 If you have two different applications which run on the same machine,
48 which need two different versions of a library then the only way to do
49 this is to have per-vhost perl interpreters (with different library paths).
50 This is entirely possible, but nullifies all the memory sharing benefits that
51 you get from having multiple applications sharing the same interpreter.
55 Now that we have that out of the way, let's talk about setting up mod_perl
56 to run a Catalyst app.
58 =head4 1. Install Catalyst::Engine::Apache
60 You should install the latest versions of both Catalyst and
61 Catalyst::Engine::Apache. The Apache engines were separated from the
62 Catalyst core in version 5.50 to allow for updates to the engine without
63 requiring a new Catalyst release.
65 =head4 2. Install Apache with mod_perl
67 Both Apache 1.3 and Apache 2 are supported, although Apache 2 is highly
68 recommended. With Apache 2, make sure you are using the prefork MPM and not
69 the worker MPM. The reason for this is that many Perl modules are not
70 thread-safe and may have problems running within the threaded worker
71 environment. Catalyst is thread-safe however, so if you know what you're
72 doing, you may be able to run using worker.
74 In Debian, the following commands should get you going.
76 apt-get install apache2-mpm-prefork
77 apt-get install libapache2-mod-perl2
79 =head4 3. Configure your application
81 Every Catalyst application will automagically become a mod_perl handler
82 when run within mod_perl. This makes the configuration extremely easy.
83 Here is a basic Apache 2 configuration.
85 PerlSwitches -I/var/www/MyApp/lib
90 PerlResponseHandler MyApp
93 The most important line here is C<PerlModule MyApp>. This causes mod_perl
94 to preload your entire application into shared memory, including all of your
95 controller, model, and view classes and configuration. If you have -Debug
96 mode enabled, you will see the startup output scroll by when you first
99 For an example Apache 1.3 configuration, please see the documentation for
100 L<Catalyst::Engine::Apache::MP13>.
104 That's it, your app is now a full-fledged mod_perl application! Try it out
105 by going to http://your.server.com/.
109 =head4 Non-root location
111 You may not always want to run your app at the root of your server or virtual
112 host. In this case, it's a simple change to run at any non-root location
117 PerlResponseHandler MyApp
120 When running this way, it is best to make use of the C<uri_for> method in
121 Catalyst for constructing correct links.
123 =head4 Static file handling
125 Static files can be served directly by Apache for a performance boost.
127 DocumentRoot /var/www/MyApp/root
129 SetHandler default-handler
132 This will let all files within root/static be handled directly by Apache. In
133 a two-tiered setup, the frontend server should handle static files.
134 The configuration to do this on the frontend will vary.
136 The same is accomplished in lighttpd with the following snippet:
138 $HTTP["url"] !~ "^/(?:img/|static/|css/|favicon.ico$)" {
142 "socket" => "/tmp/myapp.socket",
143 "check-local" => "disable",
149 Which serves everything in the img, static, css directories
150 statically, as well as the favicon file.
152 Note the path of the application needs to be stated explicitly in the
153 web server configuration for both these recipes.
155 =head2 Catalyst on shared hosting
157 So, you want to put your Catalyst app out there for the whole world to
158 see, but you don't want to break the bank. There is an answer - if you
159 can get shared hosting with FastCGI and a shell, you can install your
160 Catalyst app in a local directory on your shared host. First, run
164 and go through the standard CPAN configuration process. Then exit out
165 without installing anything. Next, open your .bashrc and add
167 export PATH=$HOME/local/bin:$HOME/local/script:$PATH
168 perlversion=`perl -v | grep 'built for' | awk '{print $4}' | sed -e 's/v//;'`
169 export PERL5LIB=$HOME/local/share/perl/$perlversion:$HOME/local/lib/perl/$perlversion:$HOME/local/lib:$PERL5LIB
171 and log out, then back in again (or run C<". .bashrc"> if you
172 prefer). Finally, edit C<.cpan/CPAN/MyConfig.pm> and add
174 'make_install_arg' => qq[SITEPREFIX=$ENV{HOME}/local],
175 'makepl_arg' => qq[INSTALLDIRS=site install_base=$ENV{HOME}/local],
177 Now you can install the modules you need using CPAN as normal; they
178 will be installed into your local directory, and perl will pick them
179 up. Finally, change directory into the root of your virtual host and
180 symlink your application's script directory in:
182 cd path/to/mydomain.com
183 ln -s ~/lib/MyApp/script script
185 And add the following lines to your .htaccess file (assuming the server
186 is setup to handle .pl as fcgi - you may need to rename the script to
187 myapp_fastcgi.fcgi and/or use a SetHandler directive):
190 RewriteCond %{REQUEST_URI} !^/?script/myapp_fastcgi.pl
191 RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L]
193 Now C<http://mydomain.com/> should now Just Work. Congratulations, now
194 you can tell your friends about your new website (or in our case, tell
195 the client it's time to pay the invoice :) )
197 =head2 FastCGI Deployment
199 FastCGI is a high-performance extension to CGI. It is suitable
200 for production environments.
206 FastCGI performs equally as well as mod_perl. Don't let the 'CGI' fool you;
207 your app runs as multiple persistent processes ready to receive connections
212 When using external FastCGI servers, your application runs as a standalone
213 application server. It may be restarted independently from the web server.
214 This allows for a more robust environment and faster reload times when
215 pushing new app changes. The frontend server can even be configured to
216 display a friendly "down for maintenance" page while the application is
219 =head4 Load-balancing
221 You can launch your application on multiple backend servers and allow the
222 frontend web server to load-balance between all of them. And of course, if
223 one goes down, your app continues to run fine.
225 =head4 Multiple versions of the same app
227 Each FastCGI application is a separate process, so you can run different
228 versions of the same app on a single server.
230 =head4 Can run with threaded Apache
232 Since your app is not running inside of Apache, the faster mpm_worker module
233 can be used without worrying about the thread safety of your application.
237 You may have to disable mod_deflate. If you experience page hangs with
238 mod_fastcgi then remove deflate.load and deflate.conf from mods-enabled/
240 =head4 More complex environment
242 With FastCGI, there are more things to monitor and more processes running
243 than when using mod_perl.
247 =head4 1. Install Apache with mod_fastcgi
249 mod_fastcgi for Apache is a third party module, and can be found at
250 L<http://www.fastcgi.com/>. It is also packaged in many distributions,
251 for example, libapache2-mod-fastcgi in Debian. You will also need to install
252 the L<FCGI> module from cpan.
254 Important Note! If you experience difficulty properly rendering pages,
255 try disabling Apache's mod_deflate (Deflate Module), e.g. 'a2dismod deflate'.
257 =head4 2. Configure your application
259 # Serve static content directly
260 DocumentRoot /var/www/MyApp/root
261 Alias /static /var/www/MyApp/root/static
263 FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -processes 3
264 Alias /myapp/ /var/www/MyApp/script/myapp_fastcgi.pl/
266 # Or, run at the root
267 Alias / /var/www/MyApp/script/myapp_fastcgi.pl/
269 The above commands will launch 3 app processes and make the app available at
272 =head3 Standalone server mode
274 While not as easy as the previous method, running your app as an external
275 server gives you much more flexibility.
277 First, launch your app as a standalone server listening on a socket.
279 script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 -p /tmp/myapp.pid -d
281 You can also listen on a TCP port if your web server is not on the same
284 script/myapp_fastcgi.pl -l :8080 -n 5 -p /tmp/myapp.pid -d
286 You will probably want to write an init script to handle starting/stopping
287 of the app using the pid file.
289 Now, we simply configure Apache to connect to the running server.
291 # 502 is a Bad Gateway error, and will occur if the backend server is down
292 # This allows us to display a friendly static page that says "down for
294 Alias /_errors /var/www/MyApp/root/error-pages
295 ErrorDocument 502 /_errors/502.html
297 FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket
298 Alias /myapp/ /tmp/myapp.fcgi/
300 # Or, run at the root
301 Alias / /tmp/myapp.fcgi/
305 L<Catalyst::Engine::FastCGI>.
307 =head2 Development server deployment
309 The development server is a mini web server written in perl. If you
310 expect a low number of hits or you don't need mod_perl/FastCGI speed,
311 you could use the development server as the application server with a
312 lightweight proxy web server at the front. However, consider using
313 L<Catalyst::Engine::HTTP::Prefork> for this kind of deployment instead, since
314 it can better handle multiple concurrent requests without forking, or can
315 prefork a set number of servers for improved performance.
319 As this is an application server setup, the pros are the same as
320 FastCGI (with the exception of speed).
325 The development server is what you create your code on, so if it works
326 here, it should work in production!
332 Not as fast as mod_perl or FastCGI. Needs to fork for each request
333 that comes in - make sure static files are served by the web server to
338 =head4 Start up the development server
340 script/myapp_server.pl -p 8080 -k -f -pidfile=/tmp/myapp.pid
342 You will probably want to write an init script to handle stop/starting
343 the app using the pid file.
345 =head4 Configuring Apache
347 Make sure mod_proxy is enabled and add:
349 # Serve static content directly
350 DocumentRoot /var/www/MyApp/root
351 Alias /static /var/www/MyApp/root/static
359 # Need to specifically stop these paths from being passed to proxy
361 ProxyPass /favicon.ico !
363 ProxyPass / http://localhost:8080/
364 ProxyPassReverse / http://localhost:8080/
366 # This is optional if you'd like to show a custom error page
367 # if the proxy is not available
368 ErrorDocument 502 /static/error_pages/http502.html
370 You can wrap the above within a VirtualHost container if you want
371 different apps served on the same host.
373 # Set up your Catalyst app as a mod_perl 2.x application in httpd.conf
374 PerlSwitches -I/var/www/MyApp/lib
376 # Preload your entire application
380 ServerName myapp.hostname.com
381 DocumentRoot /var/www/MyApp/root
385 PerlResponseHandler MyApp
388 # you can also run your app in any non-root location
389 <Location /some/other/path>
390 SetHandler perl-script
391 PerlResponseHandler MyApp
394 # Make sure to let Apache handle your static files
395 # (It is not necessary to remove the Static::Simple plugin
396 # in production; Apache will bypass Static::Simple if
397 # configured in this way)
400 SetHandler default-handler
403 # If not running at a root location in a VirtualHost,
404 # you'll probably need to set an Alias to the location
405 # of your static files, and allow access to this location:
407 Alias /myapp/static /filesystem/path/to/MyApp/root/static
408 <Directory /filesystem/path/to/MyApp/root/static>
411 <Location /myapp/static>
412 SetHandler default-handler
419 This is the Catalyst engine specialized for Apache2 mod_perl version 2.x.
421 =head1 ModPerl::Registry
423 While this method is not recommended, you can also run your Catalyst
424 application via a ModPerl::Registry script.
428 PerlModule ModPerl::Registry
429 Alias / /var/www/MyApp/script/myapp_registry.pl/
431 <Directory /var/www/MyApp/script>
436 SetHandler perl-script
437 PerlResponseHandler ModPerl::Registry
440 script/myapp_registry.pl (you will need to create this):
448 MyApp->handle_request( Apache2::RequestUtil->request );
453 Catalyst Contributors, see Catalyst.pm
457 This library is free software. You can redistribute it and/or modify it under
458 the same terms as Perl itself.