Since the first day mod_perl was available, users have adopted
various techniques that make the best of mod_perl by deploying it in
combination with other modules and tools. This chapter presents the
theory behind these useful techniques, their pros and cons, and of
course detailed installation and configuration notes so you can
easily reproduce the presented setups.

This chapter will explore various ways to use mod_perl, running it in
parallel with other web servers as well as coexisting with proxy
servers.

12.1. mod_perl Deployment Overview

There are several
different ways to build, configure, and deploy your mod_perl-enabled
server. Some of them are:

One big binary (for mod_perl) and one configuration file.

Two binaries (one big one for mod_perl and one small one for static
objects, such as images) and two configuration files.

One DSO-style Apache binary and two configuration files. The first
configuration file is used for the plain Apache server (equivalent to
a static build of Apache); the second configuration file is used for
the heavy mod_perl server, by loading the mod_perl DSO loadable
object using the same binary.

Any of the above plus a reverse proxy server in
httpd accelerator mode.

If you are new to mod_perl and just want to set up your development
server quickly, we recommend that you start with the first option and
work on getting your feet wet with Apache and mod_perl. Later, you
can decide whether to move to the second option, which allows better
tuning at the expense of more complicated administration, to the
third option (the more state-of-the-art DSO system), or to the fourth
option, which gives you even more power and flexibility. Here are
some of the things to consider.

The first option will kill your production site if you serve a lot of
static data from large (4-15 MB) web server processes. On the other
hand, while testing you will have no other server interaction to mask
or add to your errors.

The second option allows you to tune the two servers individually,
for maximum performance. However, you need to choose whether to run
the two servers on multiple ports, multiple IPs, etc., and you have
the burden of administering more than one server. You also have to
deal with proxying or complicated links to keep the two servers
synchronized.

With DSO, modules can be added and removed without recompiling the
server, and their code is even shared among multiple servers.

You can compile just once and yet have more than one binary, by using
different configuration files to load different sets of modules. The
different Apache servers loaded in this way can run simultaneously to
give a setup such as that described in the second option above.

The downside is that you are dealing with a solution that has weak
documentation, is still subject to change, and, even worse, might
cause some subtle bugs. It is still somewhat platform-specific, and
your mileage may vary.

The fourth option (proxy in httpd accelerator
mode), once correctly configured and tuned, improves the performance
of any of the above three options by caching and buffering page
results. This should be used once you have mastered the second or
third option, and is generally the preferred way to deploy a mod_perl
server in a production environment.

If you are going to run two web servers, you have the following
options:

Two machines

Serve the static content from one
machine and the dynamic content from another. You will have to adjust
all the links in the generated HTML pages: you cannot use relative
references (e.g., /images/foo.gif) for static
objects when the page is generated by the dynamic-content machine,
and conversely you can't use relative references to
dynamic objects in pages served by the static server. In these cases,
fully qualified URIs are required.

Later we will explore a frontend/backend strategy that solves this
problem.

The drawback is that you must maintain two machines, and this can get
expensive. Still, for extremely large projects, this is the best way
to go. When the load is high, it can be distributed across more than
two machines.

One machine and two IP addresses

If you have only one machine but two IP addresses, you may tell each
server to bind to a different IP address, with the help of the
BindAddress directive in
httpd.conf. You still have the problem of
relative links here (solutions to which will be presented later in
this chapter). As we will show later, you can use the 127.0.0.1
address for the backend server if the backend connections are proxied
through the frontend.

One machine, one IP address, and two ports

Finally, the most widely used approach uses only one machine and one
NIC, but binds the two servers to two different ports. Usually the
static server listens on the default port 80, and the dynamic server
listens on some other, nonstandard port.

Even here the problem of relative links is still relevant, since
while the same IP address is used, the port designators are
different, which prevents you from using relative links for both
contents. For example, a URL to the static server could be
http://www.example.com/images/nav.png, while the
dynamic page might reside at
http://www.example.com:8000/perl/script.pl. Once
again, the solutions are around the corner.