Rip the stuff out of Engine::FastCGI in master
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Deployment / Apache / mod_perl.pod
CommitLineData
1d2376f3 1=head1 NAME
2
3Catalyst::Manual::Deployment::Apache::mod_perl - Deploying Catalyst with mod_perl
4
5=head2 mod_perl Deployment
6
7mod_perl is not the best solution for many applications, but we'll list some
8pros and cons so you can decide for yourself.
9
10=head3 Pros
11
12=head4 Speed
13
14mod_perl is fast and your app will be loaded in memory
15within each Apache process.
16
17=head4 Shared memory for multiple apps
18
19If you need to run several Catalyst apps on the same server, mod_perl will
20share the memory for common modules.
21
22=head3 Cons
23
24=head4 Memory usage
25
26Since your application is fully loaded in memory, every Apache process will
27be rather large. This means a large Apache process will be tied up while
28serving static files, large files, or dealing with slow clients. For this
29reason, it is best to run a two-tiered web architecture with a lightweight
30frontend server passing dynamic requests to a large backend mod_perl
31server.
32
33=head4 Reloading
34
35Any changes made to the core code of your app require a full Apache restart.
36Catalyst does not support Apache::Reload or StatINC. This is another good
37reason to run a frontend web server where you can set up an
38C<ErrorDocument 502> page to report that your app is down for maintenance.
39
40=head4 Cannot run multiple versions of the same app
41
42It is not possible to run two different versions of the same application in
43the same Apache instance because the namespaces will collide.
44
45=head4 Cannot run different versions of libraries.
46
47If you have two different applications which run on the same machine,
48which need two different versions of a library then the only way to do
49this is to have per-vhost perl interpreters (with different library paths).
50This is entirely possible, but nullifies all the memory sharing benefits that
51you get from having multiple applications sharing the same interpreter.
52
53=head4 Setup
54
55Now that we have that out of the way, let's talk about setting up mod_perl
56to run a Catalyst app.
57
58=head4 1. Install Catalyst::Engine::Apache
59
60You should install the latest versions of both Catalyst and
61Catalyst::Engine::Apache. The Apache engines were separated from the
62Catalyst core in version 5.50 to allow for updates to the engine without
63requiring a new Catalyst release.
64
65=head4 2. Install Apache with mod_perl
66
67Both Apache 1.3 and Apache 2 are supported, although Apache 2 is highly
68recommended. With Apache 2, make sure you are using the prefork MPM and not
69the worker MPM. The reason for this is that many Perl modules are not
70thread-safe and may have problems running within the threaded worker
71environment. Catalyst is thread-safe however, so if you know what you're
72doing, you may be able to run using worker.
73
74In Debian, the following commands should get you going.
75
76 apt-get install apache2-mpm-prefork
77 apt-get install libapache2-mod-perl2
78
79=head4 3. Configure your application
80
81Every Catalyst application will automagically become a mod_perl handler
82when run within mod_perl. This makes the configuration extremely easy.
83Here is a basic Apache 2 configuration.
84
85 PerlSwitches -I/var/www/MyApp/lib
86 PerlModule MyApp
87
88 <Location />
89 SetHandler modperl
90 PerlResponseHandler MyApp
91 </Location>
92
93The most important line here is C<PerlModule MyApp>. This causes mod_perl
94to preload your entire application into shared memory, including all of your
95controller, model, and view classes and configuration. If you have -Debug
96mode enabled, you will see the startup output scroll by when you first
97start Apache.
98
99For an example Apache 1.3 configuration, please see the documentation for
100L<Catalyst::Engine::Apache::MP13>.
101
102=head3 Test It
103
104That's it, your app is now a full-fledged mod_perl application! Try it out
105by going to http://your.server.com/.
106
107=head3 Other Options
108
109=head4 Non-root location
110
111You may not always want to run your app at the root of your server or virtual
112host. In this case, it's a simple change to run at any non-root location
113of your choice.
114
115 <Location /myapp>
116 SetHandler modperl
117 PerlResponseHandler MyApp
118 </Location>
119
120When running this way, it is best to make use of the C<uri_for> method in
121Catalyst for constructing correct links.
122
123=head4 Static file handling
124
125Static files can be served directly by Apache for a performance boost.
126
127 DocumentRoot /var/www/MyApp/root
128 <Location /static>
129 SetHandler default-handler
130 </Location>
131
132This will let all files within root/static be handled directly by Apache. In
133a two-tiered setup, the frontend server should handle static files.
134The configuration to do this on the frontend will vary.
135
136The same is accomplished in lighttpd with the following snippet:
137
138 $HTTP["url"] !~ "^/(?:img/|static/|css/|favicon.ico$)" {
139 fastcgi.server = (
140 "" => (
141 "MyApp" => (
142 "socket" => "/tmp/myapp.socket",
143 "check-local" => "disable",
144 )
145 )
146 )
147 }
148
149Which serves everything in the img, static, css directories
150statically, as well as the favicon file.
151
152Note the path of the application needs to be stated explicitly in the
153web server configuration for both these recipes.
154
155=head2 Catalyst on shared hosting
156
157So, you want to put your Catalyst app out there for the whole world to
158see, but you don't want to break the bank. There is an answer - if you
159can get shared hosting with FastCGI and a shell, you can install your
160Catalyst app in a local directory on your shared host. First, run
161
162 perl -MCPAN -e shell
163
164and go through the standard CPAN configuration process. Then exit out
165without installing anything. Next, open your .bashrc and add
166
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
170
171and log out, then back in again (or run C<". .bashrc"> if you
172prefer). Finally, edit C<.cpan/CPAN/MyConfig.pm> and add
173
174 'make_install_arg' => qq[SITEPREFIX=$ENV{HOME}/local],
175 'makepl_arg' => qq[INSTALLDIRS=site install_base=$ENV{HOME}/local],
176
177Now you can install the modules you need using CPAN as normal; they
178will be installed into your local directory, and perl will pick them
179up. Finally, change directory into the root of your virtual host and
180symlink your application's script directory in:
181
182 cd path/to/mydomain.com
183 ln -s ~/lib/MyApp/script script
184
185And add the following lines to your .htaccess file (assuming the server
186is setup to handle .pl as fcgi - you may need to rename the script to
187myapp_fastcgi.fcgi and/or use a SetHandler directive):
188
189 RewriteEngine On
190 RewriteCond %{REQUEST_URI} !^/?script/myapp_fastcgi.pl
191 RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L]
192
193Now C<http://mydomain.com/> should now Just Work. Congratulations, now
194you can tell your friends about your new website (or in our case, tell
195the client it's time to pay the invoice :) )
196
197=head2 FastCGI Deployment
198
199FastCGI is a high-performance extension to CGI. It is suitable
200for production environments.
201
202=head3 Pros
203
204=head4 Speed
205
206FastCGI performs equally as well as mod_perl. Don't let the 'CGI' fool you;
207your app runs as multiple persistent processes ready to receive connections
208from the web server.
209
210=head4 App Server
211
212When using external FastCGI servers, your application runs as a standalone
213application server. It may be restarted independently from the web server.
214This allows for a more robust environment and faster reload times when
215pushing new app changes. The frontend server can even be configured to
216display a friendly "down for maintenance" page while the application is
217restarting.
218
219=head4 Load-balancing
220
221You can launch your application on multiple backend servers and allow the
222frontend web server to load-balance between all of them. And of course, if
223one goes down, your app continues to run fine.
224
225=head4 Multiple versions of the same app
226
227Each FastCGI application is a separate process, so you can run different
228versions of the same app on a single server.
229
230=head4 Can run with threaded Apache
231
232Since your app is not running inside of Apache, the faster mpm_worker module
233can be used without worrying about the thread safety of your application.
234
235=head3 Cons
236
237You may have to disable mod_deflate. If you experience page hangs with
238mod_fastcgi then remove deflate.load and deflate.conf from mods-enabled/
239
240=head4 More complex environment
241
242With FastCGI, there are more things to monitor and more processes running
243than when using mod_perl.
244
245=head3 Setup
246
247=head4 1. Install Apache with mod_fastcgi
248
249mod_fastcgi for Apache is a third party module, and can be found at
250L<http://www.fastcgi.com/>. It is also packaged in many distributions,
251for example, libapache2-mod-fastcgi in Debian. You will also need to install
252the L<FCGI> module from cpan.
253
254Important Note! If you experience difficulty properly rendering pages,
255try disabling Apache's mod_deflate (Deflate Module), e.g. 'a2dismod deflate'.
256
257=head4 2. Configure your application
258
259 # Serve static content directly
260 DocumentRoot /var/www/MyApp/root
261 Alias /static /var/www/MyApp/root/static
262
263 FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -processes 3
264 Alias /myapp/ /var/www/MyApp/script/myapp_fastcgi.pl/
265
266 # Or, run at the root
267 Alias / /var/www/MyApp/script/myapp_fastcgi.pl/
268
269The above commands will launch 3 app processes and make the app available at
270/myapp/
271
272=head3 Standalone server mode
273
274While not as easy as the previous method, running your app as an external
275server gives you much more flexibility.
276
277First, launch your app as a standalone server listening on a socket.
278
279 script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 -p /tmp/myapp.pid -d
280
281You can also listen on a TCP port if your web server is not on the same
282machine.
283
284 script/myapp_fastcgi.pl -l :8080 -n 5 -p /tmp/myapp.pid -d
285
286You will probably want to write an init script to handle starting/stopping
287of the app using the pid file.
288
289Now, we simply configure Apache to connect to the running server.
290
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
293 # maintenance"
294 Alias /_errors /var/www/MyApp/root/error-pages
295 ErrorDocument 502 /_errors/502.html
296
297 FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket
298 Alias /myapp/ /tmp/myapp.fcgi/
299
300 # Or, run at the root
301 Alias / /tmp/myapp.fcgi/
302
303=head3 More Info
304
305L<Catalyst::Engine::FastCGI>.
306
307=head2 Development server deployment
308
309The development server is a mini web server written in perl. If you
310expect a low number of hits or you don't need mod_perl/FastCGI speed,
311you could use the development server as the application server with a
312lightweight proxy web server at the front. However, consider using
313L<Catalyst::Engine::HTTP::Prefork> for this kind of deployment instead, since
314it can better handle multiple concurrent requests without forking, or can
315prefork a set number of servers for improved performance.
316
317=head3 Pros
318
319As this is an application server setup, the pros are the same as
320FastCGI (with the exception of speed).
321It is also:
322
323=head4 Simple
324
325The development server is what you create your code on, so if it works
326here, it should work in production!
327
328=head3 Cons
329
330=head4 Speed
331
332Not as fast as mod_perl or FastCGI. Needs to fork for each request
333that comes in - make sure static files are served by the web server to
334save forking.
335
336=head3 Setup
337
338=head4 Start up the development server
339
340 script/myapp_server.pl -p 8080 -k -f -pidfile=/tmp/myapp.pid
341
342You will probably want to write an init script to handle stop/starting
343the app using the pid file.
344
345=head4 Configuring Apache
346
347Make sure mod_proxy is enabled and add:
348
349 # Serve static content directly
350 DocumentRoot /var/www/MyApp/root
351 Alias /static /var/www/MyApp/root/static
352
353 ProxyRequests Off
354 <Proxy *>
355 Order deny,allow
356 Allow from all
357 </Proxy>
358
359 # Need to specifically stop these paths from being passed to proxy
360 ProxyPass /static !
361 ProxyPass /favicon.ico !
362
363 ProxyPass / http://localhost:8080/
364 ProxyPassReverse / http://localhost:8080/
365
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
369
370You can wrap the above within a VirtualHost container if you want
371different apps served on the same host.
372
373=head1 AUTHORS
374
375Catalyst Contributors, see Catalyst.pm
376
377=head1 COPYRIGHT
378
379This library is free software. You can redistribute it and/or modify it under
380the same terms as Perl itself.
381
382=cut
383