More cooked
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Deployment / Apache / mod_perl.pod
1 =head1 NAME
2
3 Catalyst::Manual::Deployment::Apache::mod_perl - Deploying Catalyst with mod_perl
4
5 =head2 mod_perl Deployment
6
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.
9
10 =head3 Pros
11
12 =head4 Speed
13
14 mod_perl is fast and your app will be loaded in memory
15 within each Apache process.
16
17 =head4 Shared memory for multiple apps
18
19 If you need to run several Catalyst apps on the same server, mod_perl will
20 share the memory for common modules.
21
22 =head3 Cons
23
24 =head4 Memory usage
25
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
31 server.
32
33 =head4 Reloading
34
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.
39
40 =head4 Cannot run multiple versions of the same app
41
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.
44
45 =head4 Cannot run different versions of libraries.
46
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.
52
53 =head4 Setup
54
55 Now that we have that out of the way, let's talk about setting up mod_perl
56 to run a Catalyst app.
57
58 =head4 1. Install Catalyst::Engine::Apache
59
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.
64
65 =head4 2. Install Apache with mod_perl
66
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.
73
74 In 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
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.
84
85     PerlSwitches -I/var/www/MyApp/lib
86     PerlModule MyApp
87
88     <Location />
89         SetHandler          modperl
90         PerlResponseHandler MyApp
91     </Location>
92
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
97 start Apache.
98
99 For an example Apache 1.3 configuration, please see the documentation for
100 L<Catalyst::Engine::Apache::MP13>.
101
102 =head3 Test It
103
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/.
106
107 =head3 Other Options
108
109 =head4 Non-root location
110
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
113 of your choice.
114
115     <Location /myapp>
116         SetHandler          modperl
117         PerlResponseHandler MyApp
118     </Location>
119
120 When running this way, it is best to make use of the C<uri_for> method in
121 Catalyst for constructing correct links.
122
123 =head4 Static file handling
124
125 Static 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
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.
135
136 The 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
149 Which serves everything in the img, static, css directories
150 statically, as well as the favicon file.
151
152 Note the path of the application needs to be stated explicitly in the
153 web server configuration for both these recipes.
154
155 =head2 Catalyst on shared hosting
156
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
161
162     perl -MCPAN -e shell
163
164 and go through the standard CPAN configuration process. Then exit out
165 without 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
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
173
174     'make_install_arg' => qq[SITEPREFIX=$ENV{HOME}/local],
175     'makepl_arg' => qq[INSTALLDIRS=site install_base=$ENV{HOME}/local],
176
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:
181
182     cd path/to/mydomain.com
183     ln -s ~/lib/MyApp/script script
184
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):
188
189   RewriteEngine On
190   RewriteCond %{REQUEST_URI} !^/?script/myapp_fastcgi.pl
191   RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L]
192
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 :) )
196
197 =head2 FastCGI Deployment
198
199 FastCGI is a high-performance extension to CGI. It is suitable
200 for production environments.
201
202 =head3 Pros
203
204 =head4 Speed
205
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
208 from the web server.
209
210 =head4 App Server
211
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
217 restarting.
218
219 =head4 Load-balancing
220
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.
224
225 =head4 Multiple versions of the same app
226
227 Each FastCGI application is a separate process, so you can run different
228 versions of the same app on a single server.
229
230 =head4 Can run with threaded Apache
231
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.
234
235 =head3 Cons
236
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/
239
240 =head4 More complex environment
241
242 With FastCGI, there are more things to monitor and more processes running
243 than when using mod_perl.
244
245 =head3 Setup
246
247 =head4 1. Install Apache with mod_fastcgi
248
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.
253
254 Important Note! If you experience difficulty properly rendering pages,
255 try 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
269 The above commands will launch 3 app processes and make the app available at
270 /myapp/
271
272 =head3 Standalone server mode
273
274 While not as easy as the previous method, running your app as an external
275 server gives you much more flexibility.
276
277 First, 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
281 You can also listen on a TCP port if your web server is not on the same
282 machine.
283
284     script/myapp_fastcgi.pl -l :8080 -n 5 -p /tmp/myapp.pid -d
285
286 You will probably want to write an init script to handle starting/stopping
287 of the app using the pid file.
288
289 Now, 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
305 L<Catalyst::Engine::FastCGI>.
306
307 =head2 Development server deployment
308
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.
316
317 =head3 Pros
318
319 As this is an application server setup, the pros are the same as
320 FastCGI (with the exception of speed).
321 It is also:
322
323 =head4 Simple
324
325 The development server is what you create your code on, so if it works
326 here, it should work in production!
327
328 =head3 Cons
329
330 =head4 Speed
331
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
334 save 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
342 You will probably want to write an init script to handle stop/starting
343 the app using the pid file.
344
345 =head4 Configuring Apache
346
347 Make 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
370 You can wrap the above within a VirtualHost container if you want
371 different apps served on the same host.
372
373 =head1 AUTHORS
374
375 Catalyst Contributors, see Catalyst.pm
376
377 =head1 COPYRIGHT
378
379 This library is free software. You can redistribute it and/or modify it under
380 the same terms as Perl itself.
381
382 =cut
383