When using a non-production development box, it is OK to start and stop the web server by hand when necessary. On a production system, however, it is possible that the machine on which the server is running will have to be rebooted. When the reboot is completed, who is going to remember to start the server? It is easy to forget this task, and what happens if no one is around when the machine is rebooted? (Some OSs will reboot themselves without human intervention in certain situations.)

After the server installation is complete, it is important to remember that a script to perform the server startup and shutdown should be put in a standard system location—for example, /etc/rc.d under Red Hat Linux, or /etc/init.d/apache under Debian GNU/Linux.

This book uses Red Hat-compatible Linux distributions in its examples. Let's step aside for a brief introduction to the System V (SysV) init system that many Linux and other Unix flavors use to manage starting and stopping daemons. (A daemon is a process that normally starts at system startup and runs in the background until the system goes down.)

The SysV init system keeps all its files in the /etc/rc.d/ directory. This directory contains a number of subdirectories:

panic% find /etc/rc.d -type d
/etc/rc.d
/etc/rc.d/init.d
/etc/rc.d/rc0.d
/etc/rc.d/rc1.d
/etc/rc.d/rc2.d
/etc/rc.d/rc3.d
/etc/rc.d/rc4.d
/etc/rc.d/rc5.d
/etc/rc.d/rc6.d

/etc/rc.d/init.d contains many scripts, one for each service that needs to be started at boot time or when entering a specific runlevel. Common services include networking, file sharing, mail servers, web servers, FTP servers, etc.

When the system boots, the special init script runs all scripts for the default runlevel. The default runlevel is specified in the /etc/inittab file. This file contains a line similar to this one:

id:3:initdefault:

The second column indicates that the default runlevel is 3, which is the default for most server systems. (5 is the default for desktop machines.)

Let's now see how the scripts are run. We'll first look at the contents of the /etc/rc.d/rc3.d directory:

panic% ls -l /etc/rc.d/rc3.d
lrwxrwxrwx 1 root root 13 Jul  1 01:08 K20nfs -> ../init.d/nfs
lrwxrwxrwx 1 root root 18 Jul  1 00:54 K92ipchains -> ../init.d
lrwxrwxrwx 1 root root 17 Jul  1 00:51 S10network -> ../init.d/network
lrwxrwxrwx 1 root root 16 Jul  1 00:51 S30syslog -> ../init.d/syslog
lrwxrwxrwx 1 root root 13 Jul  1 00:52 S40atd -> ../init.d/atd
lrwxrwxrwx 1 root root 15 Jul  1 00:51 S40crond -> ../init.d/crond
lrwxrwxrwx 1 root root 15 Jul  1 01:13 S91httpd_docs -> ../init.d/httpd_docs
lrwxrwxrwx 1 root root 15 Jul  1 01:13 S91httpd_perl -> ../init.d/httpd_perl
lrwxrwxrwx 1 root root 17 Jul  1 00:51 S95kheader -> ../init.d/kheader
lrwxrwxrwx 1 root root 11 Jul  1 00:51 S99local -> ../rc.local

(Only part of the output is shown here, since many services are started and stopped at runlevel 3.)

There are no real files in the directory. Instead, each file is a symbolic link to one of the scripts in the init.d directory. The links' names start with a letter (S or K) and a two-digit number. S specifies that the script should be run when the service is started and K specifies that the script should be run when the service is stopped. The number following S or K is there for ordering purposes: init will start services in the order in which they appear.

init runs each script with an argument that is either start or stop, depending on whether the link's name starts with S or K. Scripts can be executed from the command line; the following command line will stop the httpd server:

panic# /etc/rc.d/init.d/httpd_perl stop

Unfortunately, different Unix flavors implement different init systems. Refer to your system's documentation.

Now that we're familiar with how the init system works, let's return to our discussion of apachectl scripts.

Generally, the simplest solution is to copy the apachectl script to the startup directory or, better still, create a symbolic link from the startup directory to the apachectl script. The apachectl utility is in the same directory as the Apache executable after Apache installation (e.g., /home/httpd/httpd_perl/bin). If there is more than one Apache server, there will need to be a separate script for each one, and of course they will have to have different names so that they can coexist in the same directory.

On one of our Red Hat Linux machines with two servers, we have the following setup:

/etc/rc.d/init.d/httpd_docs
/etc/rc.d/init.d/httpd_perl
/etc/rc.d/rc3.d/S91httpd_docs -> ../init.d/httpd_docs
/etc/rc.d/rc3.d/S91httpd_perl -> ../init.d/httpd_perl
/etc/rc.d/rc6.d/K16httpd_docs -> ../init.d/httpd_docs
/etc/rc.d/rc6.d/K16httpd_perl -> ../init.d/httpd_perl

The scripts themselves reside in the /etc/rc.d/init.d directory. There are symbolic links to these scripts in /etc/rc.d/rc*.d directories.

When the system starts (runlevel 3), we want Apache to be started when all the services on which it might depend are already running. Therefore, we have used S91. If, for example, the mod_perl-enabled Apache issues a connect_on_init( ), the SQL server should be started before Apache.

When the system shuts down (runlevel 6), Apache should be one of the first processes to be stopped—therefore, we have used K16. Again, if the server does some cleanup processing during the shutdown event and requires third-party services (e.g., a MySQL server) to be running at the time, it should be stopped before these services.

Notice that it is normal for more than one symbolic link to have the same sequence number.

Under Red Hat Linux and similar systems, when a machine is booted and its runlevel is set to 3 (multiuser plus network), Linux goes into /etc/rc.d/rc3.d/ and executes the scripts to which the symbolic links point with the start argument. When it sees S87httpd_perl, it executes:

/etc/rc.d/init.d/httpd_perl start

When the machine is shut down, the scripts are executed through links from the /etc/rc.d/rc6.d/ directory. This time the scripts are called with the stop argument, like this:

/etc/rc.d/init.d/httpd_perl stop

Most systems have GUI utilities to automate the creation of symbolic links. For example, Red Hat Linux includes the ntsysv and tksysv utilities. These can be used to create the proper symbolic links. Before it is used, the apachectl or similar scripts should be put into the init.d directory or an equivalent directory. Alternatively, a symbolic link to some other location can be created.

However, it's been reported that sometimes these tools mess up and break things. Therefore, the robust chkconfig utility should be used instead. The following example shows how to add an httpd_perl startup script to the system using chkconfig.

The apachectl script may be kept in any directory, as long as it can be the target of a symbolic link. For example, it might be desirable to keep all Apache executables in the same directory (e.g., /home/httpd/httpd_perl/bin), in which case all that needs to be done is to provide a symbolic link to this file:

panic% ln -s /home/httpd/httpd_perl/bin/apachectl /etc/rc.d/init.d/httpd_perl

Edit the apachectl script to add the following lines after the script's main header:

# Comments to support chkconfig on RedHat Linux
# chkconfig: 2345 91 16
# description: mod_perl enabled Apache Server

Now the beginning of the script looks like:

#!/bin/sh
#
# Apache control script designed to allow an easy command line
# interface to controlling Apache.  Written by Marc Slemko,
# 1997/08/23

# Comments to support chkconfig on Red Hat Linux
# chkconfig: 2345 91 16
# description: mod_perl-enabled Apache Server

#
# The exit codes returned are:
# ...

Adjust the line:

# chkconfig: 2345 91 16

to suit your situation. For example, the setting used above says the script should be started in levels 2, 3, 4, and 5, that its start priority should be 91, and that its stop priority should be 16.

Now all you need to do is ask chkconfig to configure the startup scripts. Before doing so, it is best to check what files and links are in place:

panic% find /etc/rc.d | grep httpd_perl

/etc/rc.d/init.d/httpd_perl

This response means that only the startup script itself exists. Now execute:

panic% chkconfig --add httpd_perl

and repeat the find command to see what has changed:

panic% find /etc/rc.d | grep httpd_perl

/etc/rc.d/init.d/httpd_perl
/etc/rc.d/rc0.d/K16httpd_perl
/etc/rc.d/rc1.d/K16httpd_perl
/etc/rc.d/rc2.d/S91httpd_perl
/etc/rc.d/rc3.d/S91httpd_perl
/etc/rc.d/rc4.d/S91httpd_perl
/etc/rc.d/rc5.d/S91httpd_perl
/etc/rc.d/rc6.d/K16httpd_perl

The chkconfig program has created all the required symbolic links using the startup and shutdown priorities as specified in the line:

# chkconfig: 2345 91 16

If for some reason it becomes necessary to remove the service from the startup scripts, chkconfig can perform the removal of the links automatically:

panic% chkconfig --del httpd_perl

By running the find command once more, you can see that the symbolic links have been removed and only the original file remains:

panic% find /etc/rc.d | grep httpd_perl

/etc/rc.d/init.d/httpd_perl

Again, execute:

panic% chkconfig --add httpd_perl

Note that when using symbolic links, the link name in /etc/rc.d/init.d is what matters, not the name of the script to which the link points.