Installing Apache 2.0

One of the tasks I wanted my VIA machine to perform was that of a webserver. The most popular free webserver around today is Apache. Many will tell you that it is incredibly well documented - all I can say is that as far as documentation goes there is certainly a lot of it. However it neglects to point out what seem to me to be the bloody obvious things one needs to know at the start, instead diving straight in to stuff that will leave the new user utterly bewildered.


Installing Apache on Debian Linux is extremely easy. Simply use apt-get in the normal way:

> apt-get install apache2

No problem here, the packages are retrieved, everything is installed, couldn't be any easier. If you point a browser on another machine to look at the address of the VIA, you see the familiar (tediously familiar, in my case) Apache default page that announces 'Seeing this instead of the website you expected?'. Well, yes, actually. So how exactly do I go about sorting that out then?


Here's the rub. Apache is a pain in the arse to configure, particularly if you have never done it before. Now, I have installed Apache (various versions) on several different machines and each time it has been different (and a hassle). Commonest problems: Well, let's start off by looking at the Apache configuration file. This is what Apache reads at startup to see how it should be configured, so it's something we will almost certainly need to modify (or at least know the location of). The documentation helpfully informs us that the 'main configuration file is usually called httpd.conf'. Let's look for that on the system.

> slocate httpd.conf /etc/apache2/httpd.conf

Bingo! This will be our configuration file, filled with settings to change... let's take a look.

# This is here for backwards compatability reasons and to support # installing 3rd party modules directly via apxs2, rather than # through the /etc/apache2/mods-{available,enabled} mechanism. # #LoadModule mod_placeholder /usr/lib/apache2/modules/

What? The important file 'httpd.conf' is now only 'here for backwards compatibility reasons'? When did it decide to leave? This is the start of things that really piss me off about Apache... there's more.

OK, so we don't have a 'httpd.conf' file (apparently), and the file in its place doesn't give us a hint of where its replacement might be found. To be absolutely fair, the documentation did say the configuration file is 'usually called' httpd.conf - not that it always would be. Still, if you did change it, it would be good to let the user know, right?

So, in desperation, let's look for other files with the ending .conf - we might find something.

> slocate .conf | less

This finds hundreds of files (hence the use of less) - but, scrolling painfully down the list, we see:

... /etc/apache2/apache2.conf ...

This is promising, it's in the same directory as the other file and it looks like it could be a configuration file related to Apache 2.0. Let's take a look.

# Based upon the NCSA server configuration files originally by Rob McCool. # Changed extensively for the Debian package by Daniel Stone <> # and also by Thom May <>. # ServerRoot: The top of the directory tree under which the server's # configuration, error, and log files are kept. # # NOTE! If you intend to place this on an NFS (or otherwise network) # mounted filesystem then please read the LockFile documentation # (available at <URL:>); # you will save yourself a lot of trouble. ServerRoot "/etc/apache2" # The LockFile directive sets the path to the lockfile used when Apache # is compiled with either USE_FCNTL_SERIALIZED_ACCEPT or # USE_FLOCK_SERIALIZED_ACCEPT. This directive should normally be left at # its default value. The main reason for changing it is if the logs # directory is NFS mounted, since the lockfile MUST BE STORED ON A LOCAL # DISK. The PID of the main server process is automatically appended to # the filename. LockFile /var/lock/apache2/accept.lock # PidFile: The file in which the server should record its process # identification number when it starts. PidFile /var/run/ # Timeout: The number of seconds before receives and sends time out. Timeout 300 # KeepAlive: Whether or not to allow persistent connections (more than # one request per connection). Set to "Off" to deactivate. KeepAlive On # MaxKeepAliveRequests: The maximum number of requests to allow # during a persistent connection. Set to 0 to allow an unlimited amount. # We recommend you leave this number high, for maximum performance. MaxKeepAliveRequests 100 # KeepAliveTimeout: Number of seconds to wait for the next request from the # same client on the same connection. KeepAliveTimeout 15 ## ## Server-Pool Size Regulation (MPM specific) ## # prefork MPM # StartServers ......... number of server processes to start # MinSpareServers ...... minimum number of server processes which are kept spare # MaxSpareServers ...... maximum number of server processes which are kept spare # MaxClients ........... maximum number of server processes allowed to start # MaxRequestsPerChild .. maximum number of requests a server process serves <IfModule prefork.c> StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxClients 20 MaxRequestsPerChild 0 </IfModule> # pthread MPM # StartServers ......... initial number of server processes to start # MaxClients ........... maximum number of server processes allowed to start # MinSpareThreads ...... minimum number of worker threads which are kept spare # MaxSpareThreads ...... maximum number of worker threads which are kept spare # ThreadsPerChild ...... constant number of worker threads in each server process # MaxRequestsPerChild .. maximum number of requests a server process serves <IfModule worker.c> StartServers 2 MaxClients 150 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 </IfModule> # perchild MPM # NumServers ........... constant number of server processes # StartThreads ......... initial number of worker threads in each server process # MinSpareThreads ...... minimum number of worker threads which are kept spare # MaxSpareThreads ...... maximum number of worker threads which are kept spare # MaxThreadsPerChild ... maximum number of worker threads in each server process # MaxRequestsPerChild .. maximum number of connections per server process (then it dies) <IfModule perchild.c> NumServers 5 StartThreads 5 MinSpareThreads 5 MaxSpareThreads 10 MaxThreadsPerChild 20 MaxRequestsPerChild 0 AcceptMutex fcntl </IfModule> User www-data Group www-data # The following directives define some format nicknames for use with # a CustomLog directive (see below). LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent # Global error log. ErrorLog /var/log/apache2/error.log # Include module configuration: Include /etc/apache2/mods-enabled/*.load Include /etc/apache2/mods-enabled/*.conf # Include all the user configurations: Include /etc/apache2/httpd.conf # Include ports listing Include /etc/apache2/ports.conf # Include generic snippets of statements Include /etc/apache2/conf.d/[^.#]* #Let's have some Icons, shall we? Alias /icons/ "/usr/share/apache2/icons/" <Directory "/usr/share/apache2/icons"> Options Indexes MultiViews AllowOverride None Order allow,deny Allow from all </Directory> # Set up the default error docs. # # Customizable error responses come in three flavors: # 1) plain text 2) local redirects 3) external redirects # # Some examples: #ErrorDocument 500 "The server made a boo boo." #ErrorDocument 404 /missing.html #ErrorDocument 404 "/cgi-bin/" #ErrorDocument 402 # # # Putting this all together, we can Internationalize error responses. # # We use Alias to redirect any /error/HTTP_<error>.html.var response to # our collection of by-error message multi-language collections. We use # includes to substitute the appropriate text. # # You can modify the messages' appearance without changing any of the # default HTTP_<error>.html.var files by adding the line; # # Alias /error/include/ "/your/include/path/" # # which allows you to create your own set of files by starting with the # /usr/local/apache2/error/include/ files and # copying them to /your/include/path/, even on a per-VirtualHost basis. # <IfModule mod_negotiation.c> <IfModule mod_include.c> Alias /error/ "/usr/share/apache2/error/" <Directory "/usr/share/apache2/error"> AllowOverride None Options IncludesNoExec AddOutputFilter Includes html AddHandler type-map var Order allow,deny Allow from all LanguagePriority en es de fr ForceLanguagePriority Prefer Fallback </Directory> ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var ErrorDocument 410 /error/HTTP_GONE.html.var ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var ErrorDocument 415 /error/HTTP_SERVICE_UNAVAILABLE.html.var ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var </IfModule> </IfModule> DirectoryIndex index.html index.cgi index.php index.xhtml # UserDir is now a module #UserDir public_html #UserDir disabled root #<Directory /home/*/public_html> # AllowOverride FileInfo AuthConfig Limit # Options Indexes SymLinksIfOwnerMatch IncludesNoExec #</Directory> AccessFileName .htaccess <Files ~ "^\.ht"> Order allow,deny Deny from all </Files> UseCanonicalName Off TypesConfig /etc/mime.types DefaultType text/plain HostnameLookups Off IndexOptions FancyIndexing VersionSort AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip AddIconByType (TXT,/icons/text.gif) text/* AddIconByType (IMG,/icons/image2.gif) image/* AddIconByType (SND,/icons/sound2.gif) audio/* AddIconByType (VID,/icons/movie.gif) video/* # This really should be .jpg. AddIcon /icons/binary.gif .bin .exe AddIcon /icons/binhex.gif .hqx AddIcon /icons/tar.gif .tar AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip AddIcon /icons/a.gif .ps .ai .eps AddIcon /icons/layout.gif .html .shtml .htm .pdf AddIcon /icons/text.gif .txt AddIcon /icons/c.gif .c AddIcon /icons/p.gif .pl .py AddIcon /icons/f.gif .for AddIcon /icons/dvi.gif .dvi AddIcon /icons/uuencoded.gif .uu AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl AddIcon /icons/tex.gif .tex AddIcon /icons/bomb.gif core AddIcon /icons/back.gif .. AddIcon /icons/hand.right.gif README AddIcon /icons/folder.gif ^^DIRECTORY^^ AddIcon /icons/blank.gif ^^BLANKICON^^ # This is from Matty J's patch. Anyone want to make the icons? #AddIcon /icons/dirsymlink.jpg ^^SYMDIR^^ #AddIcon /icons/symlink.jpg ^^SYMLINK^^ DefaultIcon /icons/unknown.gif ReadmeName README.html HeaderName HEADER.html IndexIgnore .??* *~ *# HEADER* RCS CVS *,t AddEncoding x-compress Z AddEncoding x-gzip gz tgz AddLanguage da .dk AddLanguage nl .nl AddLanguage en .en AddLanguage et .et AddLanguage fr .fr AddLanguage de .de AddLanguage el .el AddLanguage it .it AddLanguage ja .ja AddLanguage pl .po AddLanguage ko .ko AddLanguage pt .pt AddLanguage no .no AddLanguage pt-br .pt-br AddLanguage ltz .ltz AddLanguage ca .ca AddLanguage es .es AddLanguage sv .se AddLanguage cz .cz AddLanguage ru .ru AddLanguage tw .tw AddLanguage zh-tw .tw LanguagePriority en da nl et fr de el it ja ko no pl pt pt-br ltz ca es sv tw #AddDefaultCharset ISO-8859-1 AddCharset ISO-8859-1 .iso8859-1 .latin1 AddCharset ISO-8859-2 .iso8859-2 .latin2 .cen AddCharset ISO-8859-3 .iso8859-3 .latin3 AddCharset ISO-8859-4 .iso8859-4 .latin4 AddCharset ISO-8859-5 .iso8859-5 .latin5 .cyr .iso-ru AddCharset ISO-8859-6 .iso8859-6 .latin6 .arb AddCharset ISO-8859-7 .iso8859-7 .latin7 .grk AddCharset ISO-8859-8 .iso8859-8 .latin8 .heb AddCharset ISO-8859-9 .iso8859-9 .latin9 .trk AddCharset ISO-2022-JP .iso2022-jp .jis AddCharset ISO-2022-KR .iso2022-kr .kis AddCharset ISO-2022-CN .iso2022-cn .cis AddCharset Big5 .Big5 .big5 # For russian, more than one charset is used (depends on client, mostly): AddCharset WINDOWS-1251 .cp-1251 .win-1251 AddCharset CP866 .cp866 AddCharset KOI8-r .koi8-r .koi8-ru AddCharset KOI8-ru .koi8-uk .ua AddCharset ISO-10646-UCS-2 .ucs2 AddCharset ISO-10646-UCS-4 .ucs4 AddCharset UTF-8 .utf8 AddCharset GB2312 .gb2312 .gb AddCharset utf-7 .utf7 AddCharset utf-8 .utf8 AddCharset big5 .big5 .b5 AddCharset EUC-TW .euc-tw AddCharset EUC-JP .euc-jp AddCharset EUC-KR .euc-kr AddCharset shift_jis .sjis #AddType application/x-httpd-php .php #AddType application/x-httpd-php-source .phps AddType application/x-tar .tgz # To use CGI scripts outside /cgi-bin/: # #AddHandler cgi-script .cgi # To use server-parsed HTML files # <FilesMatch "\.shtml(\..+)?$"> SetOutputFilter INCLUDES </FilesMatch> # If you wish to use server-parsed imagemap files, use # #AddHandler imap-file map BrowserMatch "Mozilla/2" nokeepalive BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 BrowserMatch "RealPlayer 4\.0" force-response-1.0 BrowserMatch "Java/1\.0" force-response-1.0 BrowserMatch "JDK/1\.0" force-response-1.0 # # The following directive disables redirects on non-GET requests for # a directory that does not include the trailing slash. This fixes a # problem with Microsoft WebFolders which does not appropriately handle # redirects for folders with DAV methods. # BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully BrowserMatch "^WebDrive" redirect-carefully BrowserMatch "^gnome-vfs" redirect-carefully BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully # Allow server status reports, with the URL of http://servername/server-status # Change the "" to match your domain to enable. # #<Location /server-status> # SetHandler server-status # Order deny,allow # Deny from all # Allow from #</Location> # Allow remote server configuration reports, with the URL of # http://servername/server-info (requires that mod_info.c be loaded). # Change the "" to match your domain to enable. # #<Location /server-info> # SetHandler server-info # Order deny,allow # Deny from all # Allow from #</Location> # Include the virtual host configurations: Include /etc/apache2/sites-enabled/[^.#]*

Hurrah! Yes, this looks like an Apache configuration file.

Dissecting the configuration file

We learn a number of important things from this file. Firstly, the ServerRoot directive, which in this case is set to /etc/apache2. This tells us the base directory for the web server is - i.e. where most things are installed.

total 41 -rw-r--r-- 1 root root 12542 2005-10-29 12:43 apache2.conf drwxr-xr-x 2 root root 1024 2005-10-13 06:42 conf.d -rw-r--r-- 1 root root 748 2005-09-05 01:10 envvars -rw-r--r-- 1 root root 268 2005-10-13 06:42 httpd.conf -rw-r--r-- 1 root root 12441 2005-09-05 01:16 magic drwxr-xr-x 2 root root 2048 2005-10-13 06:55 mods-available drwxr-xr-x 2 root root 1024 2005-10-13 06:55 mods-enabled -rw-r--r-- 1 root root 10 2005-10-13 06:42 ports.conf -rw-r--r-- 1 root root 2266 2005-09-05 01:16 README drwxr-xr-x 2 root root 1024 2005-10-13 06:42 sites-available drwxr-xr-x 2 root root 1024 2005-10-13 06:42 sites-enabled drwxr-xr-x 2 root root 1024 2005-09-05 01:15 ssl

The second useful thing is the line in the config file that gives the location of the server error logs (not in the default location, naturally).

# Global error log. ErrorLog /var/log/apache2/error.log

Now let's have a look at that interesting README file.

Apache2 Configuration under Debian GNU/Linux ============================================ Debian's default Apache2 installation attempts to make adding and removing modules, virtual hosts, and extra configuration directives as flexible is possible, in order to make automating the changes and administering the server as easy as possible. Files and Directories in /etc/apache2: ------------------------------------- apache2.conf This is the main configuration file. conf.d/ Files in this directory are included by this line in apache2.conf: # Include generic snippets of statements Include /etc/apache2/conf.d This is a good place to add additional configuration directives. httpd.conf Empty file. magic Magic data for mod_mime_magic Apache module, documented in htdocs/manual/mod/mod_mime_magic.html. You probably don't need to touch this. mods-available/ This directory contains a series of .load and .conf files. The .load files contain the Apache configuration directive necessary to load the module in question. The respective .conf files contain configuration directives necessary to utilize the module in question. mods-enabled/ To actually enable a module for Apache2, it is necessary to create a symlink in this directory to the .load (and .conf, if it exists) files associated with the module in mods-available/. For example: cgi.load -> /etc/apache2/mods-available/cgi.load ports.conf Configuration directives for which ports and IP addresses to listen to. sites-available/ Like mods-available/, except it contains configuration directives for different virtual hosts that might be used with apache2. Note that the hostname doesn't have to correspond exactly with the filename. 'default' is the default host. sites-enabled/ Similar in functionality to mods-enabled/, sites-enabled contains symlinks to sites in sites-available/ that the admnistrator wishes to enable. Example: dedasys -> /etc/apache2/sites-available/dedasys Tools ----- Currently, a2enmod and a2dismod are available for enabling and disabling modules utilizing the above configuration system. a2ensite and a2dissite have been added, which do essentially the same thing as the above tools, but for sites rather than modules.

Hmm. Not much in there that we need at the moment. However, how do we get this first page up and running?

Browsing the apache2.conf file doesn't help. However a bit of a search on the web reveals that there is a directive called DocumentRoot, which apparently sets the directory from which the web server will serve files - hence, this is where you should put your files. This directive doesn't appear anywhere in our supplied apache2.conf file, but it does have a default value, which is given as /usr/local/apache/htdocs. A check on my system shows that this directory doesn't exist - which means it's not a lot of good making it the default location! The documentation points out that if the DocumentRoot value is not specified by your configuration file, the default value will be used instead.

Maybe if I create this directory myself, put a simple file in it, and restart the web server it will be seen?

> cd /usr/local/apache/htdocs bash: cd: /usr/local/apache/htdocs: No such file or directory > mkdir /usr/local/apache > mkdir /usr/local/apache/htdocs > cd /usr/local/apache/htdocs > vi index.html {Create a simple page} >apache2 -k restart

No luck. A web browser pointed at the machine (or a web browser on the machine pointed at http://localhost) gets the default Apache page.

Just because you can never be quite sure if you are seeing quite what you think, let's try stopping the web server and making sure we don't keep getting a page delivered to us.

> apache2 -k stop

Now, trying to reload the page pointed to by the URL http://localhost returns an error: The connection was refused when attempting to contact localhost. So, we do appear to be able to turn the server on and off!

'sites-enabled' and 'sites-available'

It turns out that configuration directives exist in not only the 'master' config file (apache2.conf in our case) but also in two subdirectories: /etc/apache2/sites-available and /etc/apache2/sites-enabled. The later simply contains symbolic links to files in the former (to see the links, do ls -l in the directory /etc/apache2/sites-enabled.)

After a plain Apache 2.0 installation (under Debian at least), /etc/apache2/sites-available contains one file, named default. Let's examine the contents of this file.

NameVirtualHost * <VirtualHost *> ServerAdmin webmaster@localhost DocumentRoot /var/www/ <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all # This directive allows us to have apache2's default start page # in /apache2-default/, but still have / go to the right place RedirectMatch ^/$ /apache2-default/ </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory> ErrorLog /var/log/apache2/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/log/apache2/access.log combined ServerSignature On Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews FollowSymLinks AllowOverride None Order deny,allow Deny from all Allow from ::1/128 </Directory> </VirtualHost>

As someone in the Usenet group alt.apache.configuration kindly helped me discover, the problem here is the line

RedirectMatch ^/$ /apache2-default/

What this does is redirect a page request if the address string (i.e. the URL) matches the regular expression ^/$. Now this particular regular expression happens to mean 'the trailing slash at the end of a line' - so guess what happens?

Right - an address such as '' gets unhelpfully redirected to the default Apache page. Why on earth was this left set in that way? I can only assume it was slipped through the net somehow.

How to fix this problem?

So, the payoff for anyone else having this trouble is to edit the file /etc/apache2/sites-available/default and make sure the line RedirectMatch ^/$ /apache2-default/ is commented out, so that it reads # RedirectMatch ^/$ /apache2-default/. Save the file, and restart Apache with the command

> apache2ctl restart

Everything should then work.

Oh, and don't forget that your HTML documents should be placed in the directory /var/www/.