--- /dev/null
+=head1 NAME
+
+Catalyst::Manual::Deployment::Apache::mod_perl - Deploying Catalyst with mod_perl
+
+=head2 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
+
+=head4 Speed
+
+mod_perl is fast and your app will be loaded in memory
+within each Apache process.
+
+=head4 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
+
+=head4 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.
+
+=head4 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
+C<ErrorDocument 502> page to report that your app is down for maintenance.
+
+=head4 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.
+
+=head4 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 to have per-vhost perl interpreters (with different library paths).
+This is entirely possible, but nullifies all the memory sharing benefits that
+you get from having multiple applications sharing the same interpreter.
+
+=head4 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
+
+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
+
+=head4 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 C<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
+L<Catalyst::Engine::Apache::MP13>.
+
+=head3 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
+
+=head4 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 C<uri_for> method in
+Catalyst for constructing correct links.
+
+=head4 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.
+
+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.
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut
+