Table of Contents:
Make sure you have perl installed -- the newer stable version you have the
better (minimum perl.5.004!). If you don't have it -- install it. Follow
the instructions in the distribution's INSTALL
file. During the configuration stage (while running ./Configure
), make sure you answer YES
to the question:
Do you wish to use dynamic loading? [y]
Answer y
to be able to load dynamically Perl Modules extensions.
It is a good idea to try to install the apache webserver without mod_perl first. This way, if something goes wrong, you will know that it's not the apache server's problem. But you can skip this stage if you already have a working (non-mod_perl) apache server, or if you are just the daring type. In any case you should unpack the apache source distribution, preferably at the same level as the mod_perl distribution.
% ls -l /usr/src drwxr-xr-x 8 stas bar 2048 Oct 6 09:46 apache_x.x.x/ drwxr-xr-x 19 stas bar 4096 Oct 2 14:33 mod_perl-x.xx/
Now we come to the main point of this document.
Here I will give only a short example of mod_perl installation. You should read the Real World Scenarios Implementaion for a more complete description.
As with any perl package, the installation of mod_perl is very easy and
standard. perldoc INSTALL
will guide you through the configuration and the installation processes.
The fastest way to install would be:
% perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \ DO_HTTPD=1 USE_APACI=1 PERL_MARK_WHERE=1 EVERYTHING=1 % make && make test && make install
Note: replace x.x.x with the version numbers you actually use.
To change the installation target (either if you are not root
or you need to install a second copy for testing purposes), assuming you
use /foo/server
as a base directory, you have to run this:
% perl Makefile.PL APACHE_SRC=../apache_x.x.x/src \ DO_HTTPD=1 PERL_MARK_WHERE=1 EVERYTHING=1 \ APACHE_PREFIX=/foo/server PREFIX=/foo/server
Where PREFIX
specifies where to install the perl modules,
APACHE_PREFIX
-- the same for the apache files.
The next step is to configure the mod_perl sections of the apache configuration file. (See ModPerlConfiguration).
Fire up the server with /foo/server/sbin/apachectl start
, Look for the error reports at the error_log
file in case the server does not start up (No error message will be printed
to the console!).
There are a few ways. In older versions of apache ( < 1.3.6 ?) you could check that by running httpd -v
, it no longer works. Now you should use httpd -l
. Please notice that it is not enough to have it installed - you should of
course configure it for mod_perl and restart the server.
When starting the server, just check the error_log
file for the following message:
[Thu Dec 3 17:27:52 1998] [notice] Apache/1.3.1 (Unix) mod_perl/1.15 configured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- resuming normal operations
Assuming that you have configured the <Location /perl-status
> section in the server configuration file fetch: http://www.nowhere.com/perl-status
using your favorite Netscape browser :-)
You should see something like this:
Embedded Perl version 5.00502 for Apache/1.3.1 (Unix) mod_perl/1.19 process 50880, running since Tue Oct 6 14:31:45 1998
Knowing the port you have configured apache to listen on, you can use
telnet
to talk directly to it.
Assuming that your mod_perl enabled server listens to port 8080, telnet to
your server at port 8080, and type HEAD / HTTP/1.0
then press the <ENTER> key TWICE:
% telnet localhost 8080<ENTER> HEAD / HTTP/1.0<ENTER><ENTER>
You should see a response like this:
HTTP/1.1 200 OK Date: Tue, 01 Dec 1998 12:27:52 GMT Server: Apache/1.3.6 (Unix) mod_perl/1.19 Connection: close Content-Type: text/html Connection closed.
The line: Server: Apache/1.3.6 (Unix) mod_perl/1.19
--confirms that you do have mod_perl installed and its version is 1.19
. Of course in your case it would be the version you have installed.
However, just because you have got mod_perl linked in there, that does not mean that you have configured your server to handle Perl scripts with mod_perl. You will find the configuration assistance at ModPerlConfiguration
Another method is to invoke a CGI script which dumps the server's environment.
Copy and paste the script below (no need for the first perl calling
(shebang) line!). Let's say you named it test.pl
, saved it at the root of the CGI scripts and CGI root is mapped directly
to the
/perl
location of your server.
print "Content-type: text/html\n\n"; print "Server's environment<P>\n"; print "<TABLE>"; foreach ( keys %ENV ) { print "<TR><TD>$_ </TD><TD>$ENV{$_}</TR></TD>"; } print "</TABLE>";
Make it readable and executable by server:
% chmod a+rx test.pl
(you will want to tune permissions on the public host).
Now fetch the URL http://www.nowhere.com:8080/perl/test.pl
(replace 8080 with the port your mod_perl enabled server is listening to.
You should see something like this (the generated output was trimmed):
SERVER_SOFTWARE Apache/1.3.6 (Unix) mod_perl/1.19 GATEWAY_INTERFACE CGI-Perl/1.1 REQUEST_METHOD GET HTTP_ACCEPT image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* MOD_PERL 1.19 REQUEST_URI /perl/test.pl SCRIPT_NAME /perl/test.pl [...snipped]
Now if I run the same script in mod_cgi mode (configured with
/cgi-bin
Alias) (you will need to add the perl invocation line
#!/bin/perl
for the above script) and fetch
http://www.nowhere.com/cgi-bin/test.pl
.
SERVER_SOFTWARE Apache/1.3.6 (Unix) GATEWAY_INTERFACE CGI/1.1 [...snipped]
You will see that two variables, SERVER_SOFTWARE
and
GATEWAY_INTERFACE
, are different from the case above. This gives you a hint of how to tell
in what mode you are running in your cgi scripts. I start all my cgi
scripts that are mod_perl aware with:
BEGIN { # Auto-detect if we are running under mod_perl or CGI. $USE_MOD_PERL = ((exists $ENV{'GATEWAY_INTERFACE'} and $ENV{'GATEWAY_INTERFACE'} =~ /CGI-Perl/) or exists $ENV{'MOD_PERL'} ); # perl5.004 is a must under mod_perl require 5.004 if $USE_MOD_PERL; }
You might wonder why in the world you would need to know in what mode you
are running. For example you will want to use Apache::exit()
and not CORE::exit()
in your modules, but if you think that your script might be used in both
environments (mod_cgi vs. mod_perl), you will have to override the exit()
subroutine and to make the runtime decision of what method you will use.
Not that if you run scripts under Apache::Registry
handler, it takes care of overriding the
exit()
call for you, so it's not an issue if this is your case. For reasons and
implementations see: Using exit() and the whole Writing Mod Perl scripts and Porting plain CGIs to it page.
Yet another one. Why do I show all these approaches? While here they are serving a very simple purpose, they can be helpful in other situations.
Assuming you have the libwww-perl
(LWP
) package installed (you will need it installed in order to pass mod_perl's make test
anyway):
% lwp-request -e -d http://www.nowhere.com
Will show you all the headers. (The -d
option disables printing the response content.)
% lwp-request -e -d http://www.nowhere.com | egrep '^Server:'
To see the server's version only.
Use http://www.nowhere.com:port_number
if your server is listening to a non-default 80 port.
Yes, no problem with that. Follow the installation instructions and when
you encounter APACI_ARGS
use your home directory (or some other directory which you have write
access to) as a prefix, (e.g. /home/stas/www
), and everything will be installed there. There is a chance that some perl
libs will be not installed on your server by root and you will have to
install these locally too. See the http://www.singlesheaven.com/stas/TULARC/webmaster/myfaq.html#7
for more information on local perl installations.
So you end up with something like:
$ gunzip <apache_x.x.xx.tar.gz | tar xvf - $ gunzip <mod_perl-x.xx.tar.gz | tar xvf - $ cd mod_perl-x.xx $ perl Makefile.PL \ APACHE_SRC=../apache-1.3.X/src \ DO_HTTPD=1 \ USE_APACI=1 \ EVERYTHING=1 \ APACI_ARGS=--sbindir=/home/stas/sbin/httpd_perl, \ --sysconfdir=/home/stas/etc/httpd_perl, \ --localstatedir=/home/stas/var/httpd_perl, \ --runtimedir=/home/stas/var/httpd_perl/run, \ --logfiledir=/home/stas/var/httpd_perl/logs, \ --proxycachedir=/home/stas/var/httpd_perl/proxy
You will not be able to have the server listen to a port lower then 1024 if
you are not starting it as root
, so choose a port number above 1024. (I use 8080 in most cases). Note that
you will have to use a URL like http://www.nowhere.com:8080
in that case, but that is not a problem since usually users do not directly
access URLs to CGI scripts, but rather are directed to them from a link on
a web page or as the 'ACTION
' of a HTML form, so they should not know at all that the port is different
from the default port 80.
If you want your apache server to start automatically on system reboot, you
will need to invoke the server startup script from somewhere within the
init scripts on your host. This is often somewhere under /etc/rc.d
, but this path can vary depending upon the flavor of Unix you are using.
One more important thing to keep in mind is system resources. mod_perl is memory hungry -- if you run a lot of mod_perl processes on a public, multiuser (not dedicated) machine -- most likely the system administrator of the host will ask you to use less resources and even to shut down your mod_perl server and to find another home for it. You have a few solutions:
Reduce resources usage (see Limiting the size of the processes).
Ask your ISP if you can put a dedicated machine into their computer room and be root there.
Look for another ISP with lots of resources or one that supports mod_perl. You can find a list of these ISP at http://perl.apache.org .
Sure, you can take a look at the symbols inside the httpd executable. e.g. if you want to see whether you have enabled PERL_AUTH=1 while building the mod_perl, you do:
nm httpd | grep perl_authenticate
It is possible to determine which options were given to modperl's
Makefile.PL
during the configuration stage, so to be used later in recreating the same
build tree when rebuilding the server. This is relevant only if you did not
use the default config parameters and altered some of them during the
configuration stage.
I was into this problem many times. I am going to build something by passing some non-default parameters to the config script and then later when I need to rebuild the tool either to upgrade it or to make an identical copy at another machine, I would find that I do not remember what parameters I altered.
The best solution for this problem is to prepare the run file with all the parameters that are about to be used and then run it instead of typing it all by hand. So later I will have the script handy to be reused.
mod_perl suggests using the makepl_args.mod_perl
file which comes with mod_perl distribution. This is the file where you
should specify all the parameters you are going to use.
But if you have found yourself with a compiled tool and no traces of the
specified parameters left, usually you can still find them out, if the
sources were not make clean
'd. You will find the apache specific parameters in apache_x.x.x/config.status
and modperl's at in mod_perl_x.xx/apaci/mod_perl.config
.
While doing make test
you would notice that some of the tests are being reported as skipped. The
real reason is that you are missing some optional modules for these test to
be passed. For a hint you might want to peek at the content of each test
(you will find them all in the ./t
directory (mnemonic - t, tests). I'll list a few examples, but of course
the requirements might be changed in the future.
> modules/cookie......skipping test on this platform
install libapreq
> modules/psections...skipping test on this platform
install Devel::Symdump / Data::Dumper
> modules/request.....skipping test on this platform
libapreq
> modules/sandwich....skipping test on this platform
Apache::Sandwich
> modules/stage.......skipping test on this platform
Apache::Stage
> modules/symbol......skipping test on this platform
Devel::Symdump
Chances are that all of these are installed if you use CPAN.pm
to
install Bundle::Apache
.
There are two configuration parameters: PREP_HTTPD
and DO_HTTPD
, that you can use in:
perl Makefile.PL [options]
DO_HTTPD=1
means default to 'y
' for the two apache's
configure
utility prompts: (a) 'which source tree to configure against' and (b)
'whether to build the httpd in that tree'. PREP_HTTPD=1
just means default 'n
' to the second prompt -- meaning, do not build httpd (make) in the
apache source tree. In other words if you use PREP_HTTPD=1
the httpd will be not build. It will be build only if you use
DO_HTTPD=1
option and not use PREP_HTTPD=1
.
If you did not build the httpd, chdir to the apache source, and execute:
make
Then return to the mod_perl source and run:
make test make install
Note that you would have to do the same if you do not pass
APACHE_PREFIX=/path_to_installation_prefix
during the perl
Makefile.PL [options]
stage.
You will see this message when you try to run a httpd, if you have had a
stale old apache header layout in one of the include
paths during the build process. Do run find
(or locate
) utility in order to locate ap_mmn.h
file. In my case I have had a
/usr/local/include/ap_mmn.h
which was installed by RedHat install process. If this is the case get rid
of it, and rebuild it again.
For all RH fans, before you are going to build the apache by yourself, do:
rpm -e apache
to remove the pre-installed package first!
Yes, you should. You have to rebuild mod_perl enabled server since it has a
hard coded @INC
which points to the old perl and it is is probably linked to the an old libperl
library. You can try to modify the @INC
in the startup script (if you keep the old perl version around), but it is
better to build a fresh one to save you a mess.
If you are a user of mod_auth_dbm or mod_auth_db, you may need to edit Perl's Config
module. When Perl is configured it attempts to find libraries for ndbm,
gdbm, db, etc., for the *DBM*_File modules. By default, these libraries are
linked with Perl and remembered by the Config module. When mod_perl is configured with apache, the ExtUtils::Embed module returns these libraries to be linked with httpd so Perl extensions
will work under mod_perl. However, the order in which these libraries are
stored in
Config.pm, may confuse mod_auth_db*
. If mod_auth_db*
does not work with mod_perl, take a look at this order with the following
command:
% perl -V:libs
If -lgdbm
or -ldb
is before -lndbm
, example:
libs='-lnet -lnsl_s -lgdbm -lndbm -ldb -ldld -lm -lc -lndir -lcrypt';
Edit Config.pm and move -lgdbm
and -ldb
to the end of the list. Here's how to find Config.pm:
% perl -MConfig -e 'print "$Config{archlibexp}/Config.pm\n"'
Another solution for building Apache/mod_perl+mod_auth_dbm under Solaris is to remove the DBM and NDBM ``emulation'' from libgdbm.a. Seems Solaris already provides its own DBM and NDBM, and there's no reason to build GDBM with them (for us anyway).
In our Makefile for GDBM, we changed
OBJS = $(DBM_OF) $(NDBM_OF) $(GDBM_OF)
to
OBJS = $(GDBM_OF)
Rebuild libgdbm, then Apache/mod_perl.
Since most of the functionality that various apache mod_* modules provide
is being implemented in Apache::{*}
perl modules, it was reported that one can build an apache server with
mod_perl only. If you can reduce the problems down to whatever mod_perl can
handle, you can eliminate nearly every other module. Then basically you
will have a perl-server, with C code to handle the tricky HTTP bits. The
only module you will need to leave in is a mod_actions
.
|
||
Written by Stas Bekman.
Last Modified at 09/25/1999 |
![]() |
Use of the Camel for Perl is a trademark of O'Reilly & Associates, and is used by permission. |