There are situations when you need to
install mod_perl-enabled Apache and other components (such as Perl
libraries) into nonstandard locations. For example, you might work on
a system to which you don't have
root access, or you might need to install more
than one set of mod_perl-enabled Apache and Perl modules on the same
machine (usually when a few developers are using the same server and
want to have their setups isolated from each other, or when you want
to test a few different setups on the same machine).
We have already seen that you can install mod_perl-enabled Apache
into different directories on the system (using the
APACHE_PREFIX parameter of
Makefile.PL). Until now, all our scenarios have
installed the Perl files that are part of the mod_perl package into
the same directory as the system Perl files (usually
/usr/lib/perl5).
Now we are going to show how can you install both the Apache and the
Perl files into a nonstandard directory. We'll show
a complete installation example using stas as a
username, assuming that /home/stas is the home
directory of that user.
3.9.1. Installing Perl Modules into a Nonstandard Directory
Before we proceed,
let's look at how to install any Perl module into a
nonstandard directory. For an example, let's use the
package that includes CGI.pm and a few other
CGI::* modules.
First, you have to decide where to install the modules. The simplest
approach is to simulate the portion of the /
filesystem relevant to Perl under your home directory. Actually, we
need only two directories:
/home/stas/bin
/home/stas/lib
We don't have to create them, as they are created
automatically when the first module is installed. Ninety-nine percent
of the files will go into the lib directory.
Only occasionally does a module distribution come with Perl scripts
that are installed into the bin directory, at
which time bin will be created if it
doesn't exist.
As usual, download the package from the CPAN repository
(CGI.pm-x.xx.tar.gz), unpack it, and
chdir to the newly created directory.
Now do a standard perl Makefile.PL to create the
Makefile, but this time make use of your
nonstandard Perl installation directory instead of the default one:
panic% perl Makefile.PL PREFIX=/home/stas
Specifying PREFIX=/home/stas is the only part of
the installation process that is different from usual. Note that if
you don't like how Makefile.PL
chooses the rest of the directories, or if you are using an older
version of it that requires an explicit declaration of all the target
directories, you should do this:
make install installs all the files in the
private repository. Note that all the missing directories are created
automatically, so you don't need to create them
beforehand. Here is what it does (slightly edited):
Installing /home/stas/lib/perl5/CGI/Cookie.pm
Installing /home/stas/lib/perl5/CGI.pm
Installing /home/stas/lib/perl5/man3/CGI.3
Installing /home/stas/lib/perl5/man3/CGI::Cookie.3
Writing /home/stas/lib/perl5/auto/CGI/.packlist
Appending installation info to /home/stas/lib/perl5/perllocal.pod
If you have to use explicit target parameters instead of a single
PREFIX parameter, you will find it useful to
create a file called something like ~/.perl_dirs
(where ~ is /home/stas in
our example), containing:
From now on, any time you want to install Perl modules locally,
simply execute:
panic% perl Makefile.PL `cat ~/.perl_dirs`
panic% make
panic% make test
panic% make install
Using this technique, you can easily maintain several Perl module
repositories. For example, you could have one for production and
another for development:
3.9.2. Finding Modules Installed in Nonstandard Directories
Installing Perl
modules into
nonstandard directories is only half the battle. We also have to let
Perl know what these directories are.
Perl modules are generally placed in four main directories. To find
these directories, execute:
panic% perl -V
The output contains important information about your Perl
installation. At the end you will see:
Characteristics of this binary (from libperl):
Built under linux
Compiled at Oct 14 2001 17:59:15
@INC:
/usr/lib/perl5/5.6.1/i386-linux
/usr/lib/perl5/5.6.1
/usr/lib/perl5/site_perl/5.6.1/i386-linux
/usr/lib/perl5/site_perl/5.6.1
/usr/lib/perl5/site_perl
.
This shows us the content of the Perl special variable
@INC, which is used by Perl to look for its
modules. It is equivalent to the PATH environment
variable, used to find executable programs in Unix shells.
Notice that Perl looks for modules in the . directory too, which
stands for the current directory. It's the last
entry in the above output.
This example is from Perl Version 5.6.1, installed on our x86
architecture PC running Linux. That's why you see
i386-linux and 5.6.1. If
your system runs a different version of Perl, or a different
operating system, processor, or chipset architecture, then some of
the directories will have different names.
All the platform-specific files (such as compiled C files glued to
Perl with XS, or some .h
header files) are supposed to go into the
i386-linux-like directories. Pure Perl modules
are stored in the non-platform-specific directories.
As mentioned earlier, you find the exact directories used by your
version of Perl by executing perl -V and
replacing the global Perl installation's base
directory with your home directory. Assuming that we use Perl 5.6.1,
in our example the directories are:
There are two ways to tell Perl about the new directories: you can
either modify the @INC variable in your scripts or
set the PERL5LIB environment variable.
3.9.2.1. Modifying @INC
Modifying@INC is quite easy. The best approach is to use
the lib module (pragma) by adding the following
snippet at the top of any of your scripts that require the locally
installed modules:
use lib qw(/home/stas/lib/perl5/5.6.1/
/home/stas/lib/perl5/site_perl/5.6.1
/home/stas/lib/perl5/site_perl
);
Another way is to write code to modify @INC
explicitly:
Note that with the lib module, we
don't have to list the corresponding
architecture-specific directories—it adds them automatically if
they exist (to be exact, when
$dir/$archname/auto exists). It also takes care
of removing any duplicated entries.
Also, notice that both approaches prepend the
directories to be searched to @INC. This allows
you to install a more recent module into your local repository, which
Perl will then use instead of the older one installed in the main
system repository.
Both approaches modify the value of @INC at
compilation time. The lib module uses the
BEGIN block internally.
3.9.2.2. Using the PERL5LIB environment variable
Now, let's assume the following scenario. We
have installed the LWP package in our local
repository. Now we want to install another module (e.g., mod_perl),
and it has LWP listed in its prerequisites list.
We know that we have LWP installed, but when we
run perl Makefile.PL for the module
we're about to install, we're told
that we don't have LWP installed.
There is no way for Perl to know that we have some locally installed
modules. All it does is search the directories listed in
@INC, and because @INC contains
only the default four directories (plus the . directory), it cannot
find the locally installed LWP package. We cannot
solve this problem by adding code to modify @INC,
but changing the PERL5LIB environment variable
will do the trick.
How to define an environment variable varies according to which shell
you use. Bourne-style shell users can split a long line using the
backslash (\):
In the C-style shells, however, you'll have to make
sure that the value of the PERL5LIB environment
variable is specified as one continuous line with no newlines or
spaces:
(In this example, the lines were split to make them fit on the page.)
As with use lib, Perl automatically prepends the
architecture-specific directories to @INC if those
exist.
When you have done this, verify the value of the newly configured
@INC by executing perl -V as
before. You should see the modified value of @INC:
panic% perl -V
Characteristics of this binary (from libperl):
Built under linux
Compiled at Apr 6 1999 23:34:07
%ENV:
PERL5LIB="/home/stas/lib/perl5/5.6.1:
/home/stas/lib/perl5/site_perl/5.6.1:
/home/stas/lib/perl5/site_perl"
@INC:
/home/stas/lib/perl5/5.6.1/i386-linux
/home/stas/lib/perl5/5.6.1
/home/stas/lib/perl5/site_perl/5.6.1/i386-linux
/home/stas/lib/perl5/site_perl/5.6.1
/home/stas/lib/perl5/site_perl
/usr/lib/perl5/5.6.1/i386-linux
/usr/lib/perl5/5.6.1
/usr/lib/perl5/site_perl/5.6.1/i386-linux
/usr/lib/perl5/site_perl/5.6.1
/usr/lib/perl5/site_perl
.
When everything works as you want it to, add these commands to your
.tcshrc, .bashrc,
C:\autoexec.bat or another equivalent
file.[21] The next time you start a
shell, the environment will be ready for you to work with the new
Perl directories.
[21]These files are run by the shell at startup and
allow you to set environment variables that might be useful every
time you use your shell.
Note that if you have a PERL5LIBsetting, you
don't need to alter the @INC
value in your scripts. But if someone else (who
doesn't have this setting in the shell) tries to
execute your scripts, Perl will fail to find your locally installed
modules. This includes cron scripts, which
might use a different shell environment (in
which case the PERL5LIBsetting
won't be available).
The best approach is to have both the PERL5LIB
environment variable and the explicit @INC
extension code at the beginning of the scripts, as described above.
3.9.3. Using the CPAN.pm Shell with Nonstandard Installation Directories
As we saw previously in this chapter, using the
CPAN.pmshell to install mod_perl saves a great
deal of time. It does the job for us, even detecting the missing
modules listed in prerequisites, fetching them, and installing them.
So you might wonder whether you can use CPAN.pm to
maintain your local repository as well.
When you start the CPAN interactive shell, it searches first for the
user's private configuration file and then for the
system-wide one. For example, for a user stas
and Perl Version 5.6.1, it will search for the following
configuration files:
If there is no CPAN shell configured on your system, when you start
the shell for the first time it will ask you a dozen configuration
questions and then create the Config.pm file for
you.
If the CPAN shell is already configured system-wide, you should
already have a
/usr/lib/perl5/5.6.1/CPAN/Config.pm file. (As
always, if you have a different Perl version, the path will include a
different version number.) Create the directory for the local
configuration file as well:
panic% mkdir -p /home/stas/.cpan/CPAN
(On many systems, mkdir -p creates the whole
path at once.)
Now copy the system-wide configuration file to your local one:
The only thing left is to change the base directory of
.cpan in your local file to the one under your
home directory. On our machine, we replace
/root/.cpan (which is where our
system's .cpan directory
resides) with /home/stas. Of course, we use Perl
to edit the file:
Now that you have the local configuration file ready, you have to
tell it what special parameters you need to pass when executing
perl Makefile.PL. Open the file in your favorite
editor and replace the following line:
'makepl_arg' => q[ ],
with:
'makepl_arg' => q[PREFIX=/home/stas],
Now you've finished the configuration. Assuming that
you are logged in with the same username used for the local
installation (stas in our example), start it
like this:
panic% perl -MCPAN -e shell
From now on, any module you try to install will be installed locally.
If you need to install some system modules, just become the superuser
and install them in the same way. When you are logged in as the
superuser, the system-wide configuration file will be used instead of
your local one.
If you have used more than just the PREFIX
variable, modify MyConfig.pm to use the other
variables. For example, if you have used these variables during the
creation of the Makefile:
If you arrange all the above parameters in one line, you can remove
the backslashes (\).
3.9.4. Making a Local Apache Installation
Just as
with Perl modules, if you
don't have the permissions required to install
Apache into the system area, you have to install them locally under
your home directory. It's almost the same as a plain
installation, but you have to run the server listening to a port
number greater than 1024 (only root processes
can listen to lower-numbered ports).
Another important issue you have to resolve is how to add startup and
shutdown scripts to the directories used by the rest of the system
services. Without root access, you
won't be able to do this yourself;
you'll have to ask your system administrator to
assist you.
To install Apache locally, all you have to do is to tell
./configure in the Apache source directory what
target directories to use. If you are following the convention that
we use, which makes your home directory look like the
/ (base) directory, the invocation parameters
will be:
panic% ./configure --prefix=/home/stas
Apache will use the prefix for the rest of its target directories,
instead of the default /usr/local/apache. If you
want to see what they are, add the
—show-layout option before you proceed:
Refer to the output of ./configure
—help
for all available options.
Also remember that you can start the script only under a user and
group to which you belong, so you must set the
User and Group directives in
httpd.conf to appropriate values.
Furthermore, as we said before, the Port directive
in httpd.conf must be adjusted to use an unused
port above 1024, such as 8080. This means that when users need to
access the locally installed server, their URLs need to specify the
port number (e.g.,
http://www.example.com:8080/). Otherwise,
browsers will access the server running on port 80, which
isn't the one you installed locally.
Now that
we
know how to install local Apache and Perl modules separately,
let's see how to install mod_perl-enabled Apache in
our home directory. It's almost as simple as doing
each one separately, but there is one wrinkle. We'll
talk about it at the end of this section.
Let's say you have unpacked the Apache and mod_perl
sources under /home/stas/src and they look like
this:
panic% ls /home/stas/src
/home/stas/src/apache_1.3.xx
/home/stas/src/mod_perl-1.xx
where x.xx are replaced by the real version
numbers, as usual. You want the Perl modules from the mod_perl
package to be installed under
/home/stas/lib/perl5 and the Apache files to go
under /home/stas/apache. The following commands
will do that for you:
panic% perl Makefile.PL \
PREFIX=/home/stas \
APACHE_PREFIX=/home/stas/apache \
APACHE_SRC=../apache_1.3.xx/src \
DO_HTTPD=1 \
USE_APACI=1 \
EVERYTHING=1
panic% make && make test && make install
panic% cd ../apache_1.3.xx
panic% make install
If you need some parameters to be passed to the
./configure script, as we saw in the previous
section, use APACI_ARGS. For example:
Note that the above multiline splitting will work only with
Bourne-style shells. C-style shell users will have to list all the
parameters on a single line.
Basically, the installation is complete. The only remaining problem
is the @INC variable. This
won't be correctly set if you rely on the
PERL5LIB environment variable unless you set it
explicitly in a startup file that is required before loading any
other module that resides in your local repository. A much nicer
approach is to use the lib pragma, as we saw
before, but in a slightly different way—we use it in the
startup file and it affects all the code that will be executed under
mod_perl handlers. For example:
PerlRequire /home/stas/apache/perl/startup.pl
where startup.pl starts with:
use lib qw(/home/stas/lib/perl5/5.6.1/
/home/stas/lib/perl5/site_perl/5.6.1
/home/stas/lib/perl5/site_perl
);
Note that you can still use the hardcoded @INC
modifications in the scripts themselves, but be aware that scripts
modify @INC in BEGIN blocks and
mod_perl executes the BEGIN blocks only when it
performs script compilation. As a result, @INC
will be reset to its original value after the scripts are compiled,
and the hardcoded settings will be forgotten.
The only time you can alter the
"original" value is during the
server configuration stage, either in the startup file or by putting
the following line in httpd.conf:
But the latter setting will be ignored if you use the
PerlTaintchecksetting, and we hope you do use it.
See the perlrun manpage for more information.
The rest of the mod_perl configuration can be done just as if you
were installing mod_perl as root.
Resource Usage
Another important
thing to keep in mind is the
consumption of system resources. mod_perl is memory-hungry. If you
run a lot of mod_perl processes on a public, multiuser machine, most
likely the system administrator of this machine will ask you to use
fewer resources and may even shut down your mod_perl server and ask
you to find another home for it. You have a few options:
Ask your ISP's system administrator whether she can
set up a dedicated machine for you, so that you will be able to
install as much memory as you need. If you get a dedicated machine,
chances are that you will want to have root
access, so you may be able to manage the administration yourself. You
should also make sure the system administrator is responsible for a
reliable electricity supply and a reliable network link. The system
administrator should also make sure that the important security
patches get applied and the machine is configured to be secure (not
to mention having the machine physically protected, so no one will
turn off the power or break it).
The best solution might be to look for another ISP with lots of
resources or one that supports mod_perl. You can find a list of these
ISPs at http://perl.apache.org/.
3.9.6. Nonstandard mod_perl-Enabled Apache Installation with CPAN.pm
Again, CPAN makes installation and upgrades
simpler. You have seen how to install a mod_perl-enabled server using
CPAN.pm's interactive shell. You
have seen how to install Perl modules and Apache locally. Now all you
have to do is to merge these techniques.
Assuming that you have configured CPAN.pm to
install Perl modules locally, the installation is very simple. Start
the CPAN shell, set the arguments to be passed to perl
Makefile.PL (modify the example setting to suit your
needs), and tell CPAN.pm to do the rest for you:
When you use CPAN.pm for local installation, you
need to make sure that the value of makepl_arg is
restored to its original value after the mod_perl installation is
complete, because if you install other Perl modules you probably
don't want to pass mod_perl flags to them. The
simplest way to do this is to quit the interactive shell and then
re-enter it. There is another way to do it without quitting, but
it's very cumbersome—if you want to learn
about the other option, refer to the CPAN.pm
manpage.