Apache2: Hosting multiple websites
www.debian-administration.org/articles/412
Posted by Steve on Thu 6 Jul 2006 at 22:03
One of the most common Apache2 questions I've seen on Debian mailing lists is from users who wonder how to host multiple websites with a single server. This is very straightforward, especially with the additional tools the Debian package provides.
We've previously discussed some of the tools which are included in the Apache2 package, but what we didn't do was show they're used from start to finish.
There are many different ways you can configure Apache to host multiple sites, ranging from the simple to the complex. Here we're only going to cover the basics with the use of the NameVirtualHost directive. The advantage of this approach is that you don't need to hard-wire any IP addresses, and it will just worktm. The only thing you need is for your domain names to resolve to the IP address of your webserver.
For example if you have an Apache server running upon the IP address 192.168.1.1 and you wish to host the three sites example.com, example.net, and example.org you'll need to make sure that these names resolve to the IP address of your server.
(This might mean that you need example.com and www.example.com to resolve to the same address. However that is a choice you'll need to make for yourself).
Since we'll be hosting multiple websites on the same host it makes a lot of sense to be very clear on the location of each sites files upon the filesystem. The way I suggest you manage this is to create a completely seperate document root, cgi-bin directory, and logfile directory for each host. You can place these beneath the standard Debian prefix of /var/www or you may use a completely different root - I use /home/www.
If you've not already done create the directories to contain your content, etc, as follows:
root@irony:~# mkdir /home/www root@irony:~# mkdir /home/www/www.example.com root@irony:~# mkdir /home/www/www.example.com/htdocs root@irony:~# mkdir /home/www/www.example.com/cgi-bin root@irony:~# mkdir /home/www/www.example.com/logs root@irony:~# mkdir /home/www/www.example.net root@irony:~# mkdir /home/www/www.example.net/htdocs root@irony:~# mkdir /home/www/www.example.net/logs root@irony:~# mkdir /home/www/www.example.net/cgi-bin root@irony:~# mkdir /home/www/www.example.org root@irony:~# mkdir /home/www/www.example.org/htdocs root@irony:~# mkdir /home/www/www.example.org/logs root@irony:~# mkdir /home/www/www.example.org/cgi-bin
Here we've setup three different directory trees, one for each site. If you wanted to have identical content it might make sense to only create one, and then use symbolic links instead.
The next thing to do is to enable virtual hosts in your Apache configuration. The simplest way to do this is to create a file called /etc/apache2/conf.d/virtual.conf and include the following content in it:
# # We're running multiple virtual hosts. # NameVirtualHost *
(When Apache starts up it reads the contents of all files included in /etc/apache2/conf.d, and files you create here won't get trashed on package upgrades.)
Once we've done this we can create the individual host configuration files. The Apache2 setup you'll find on Debian GNU/Linux includes two directories for locating your site configuration files:
- /etc/apache2/sites-available
This contains configuration files for sites which are available but not necessarily enabled.
- /etc/apache2/sites-enabled
This directory contains site files which are enabled.
As with the conf.d directory each configuration file in the sites-enabled directory is loaded when the server starts - whilst the files in sites-available are completely ignored.
You are expected to create your host configuration files in /etc/apache2/sites-available, then create a symbolic link to those files in the sites-enabled directory - this will cause them to be actually loaded/read.
Rather than actually messing around with symbolic links the Debian package includes two utility commands a2ensite and a2dissite which will do the necessary work for you as we will demonstrate shortly.
Lets start with a real example. Create /etc/apache2/sites-available/www.example.com with the following contents:
#
# Example.com (/etc/apache2/sites-available/www.example.com)
#
<VirtualHost *>
ServerAdmin webmaster@example.com
ServerName www.example.com
ServerAlias example.com
# Indexes + Directory Root.
DirectoryIndex index.html
DocumentRoot /home/www/www.example.com/htdocs/
# CGI Directory
ScriptAlias /cgi-bin/ /home/www/www.example.com/cgi-bin/
<Location /cgi-bin>
Options +ExecCGI
</Location>
# Logfiles
ErrorLog /home/www/www.example.com/logs/error.log
CustomLog /home/www/www.example.com/logs/access.log combined
</VirtualHost>
Next create the file www.example.net:
#
# Example.net (/etc/apache2/sites-available/www.example.net)
#
<VirtualHost *>
ServerAdmin webmaster@example.net
ServerName www.example.net
ServerAlias example.net
# Indexes + Directory Root.
DirectoryIndex index.html
DocumentRoot /home/www/www.example.net/htdocs/
# CGI Directory
ScriptAlias /cgi-bin/ /home/www/www.example.net/cgi-bin/
<Location /cgi-bin>
Options +ExecCGI
</Location>
# Logfiles
ErrorLog /home/www/www.example.net/logs/error.log
CustomLog /home/www/www.example.net/logs/access.log combined
</VirtualHost>
Finally create the file www.example.org:
#
# Example.org (/etc/apache2/sites-available/www.example.org)
#
<VirtualHost *>
ServerAdmin webmaster@example.org
ServerName www.example.org
ServerAlias example.org
# Indexes + Directory Root.
DirectoryIndex index.html
DocumentRoot /home/www/www.example.org/htdocs/
# CGI Directory
ScriptAlias /cgi-bin/ /home/www/www.example.org/cgi-bin/
<Location /cgi-bin>
Options +ExecCGI
</Location>
# Logfiles
ErrorLog /home/www/www.example.org/logs/error.log
CustomLog /home/www/www.example.org/logs/access.log combined
</VirtualHost>
Now we've got:
- Three directories which can be used to contain our content.
- Three directories which can be used to contain our logfiles.
- Three directories which can be used to contain our dynamic CGI scripts.
- Three configuration files which are being ignored by Apache.
To enable the sites simply run:
root@irony:~# a2ensite www.example.com Site www.example.com installed; run /etc/init.d/apache2 reload to enable. root@irony:~# a2ensite www.example.net Site www.example.net installed; run /etc/init.d/apache2 reload to enable. root@irony:~# a2ensite www.example.org Site www.example.org installed; run /etc/init.d/apache2 reload to enable.
This will now create the symbolic links so that /etc/apache2/sites-enabled/www.example.org, etc, now exist and will be read.
Once we've finished our setup we can restart, or reload, the webserver as the output above instructed us to do with:
root@irony:~# /etc/init.d/apache2 reload Reloading web server config...done. root@irony:~#
Jax Beach Technology Services

![Circuit Beach [4-5 min. walk]](http://ndc.nu/kunda/img1/tn_dsc03092.jpg)
![Circuit Beach [4-5 min. walk]](http://ndc.nu/kunda//img1/tn_dsc03081.jpg)
![Lilli Pilli Beach [6 minute walk]](http://ndc.nu/kunda//img1/tn_dsc03066.jpg)
![Lilli Pilli Beach [6 minute walk]](http://ndc.nu/kunda/img1/tn_dsc03070.jpg)








Pete F. wrote:
I like to start the page with a default font size definition in points, then use “em’s” of that point size for specific items. Works well across all browsers, including IE/Win, IE/Mac, Firefox, Opera and Safari.
Marko Samastur wrote:
Just a small comment from a math nut. 75% of 16 is 12, not 10.
So, if you want to go from 16px to 10px, you need to set font-size to 62.5% (unless browsers have their own math and 75% actually works).
Rich wrote:
Marko – thanks for that. Schoolboy error duly corrected.
James Craig wrote:
Fantastic article, and a perfect description of how to use ems. I disagree with one small part of the method though: the arbitrary body size. I’d recommend leaving the body size at 100% and scaling the rest down in ems accordingly. Of course, the downside is that the default is no longer the easily-divided 10 pixels. The upside is that it works well with user style sheets.
Imagine I was a more-technical-than-average user (more people will figure out user CSS eventually) that had a preference for larger fonts. Perhaps I had vision impairment, perhaps I had some standard hyperopia gaining with age, or perhaps I just liked reading large text better. Not too large, mind you. Just about 120% of normal. Seems easy enough in my user CSS, right?
body {font-size:120% !important;}
That is, as long as everyone uses the standard default size for the body element. Trying this one your example yields massive text. I’ve also seen other arbitrary examples like 76 percent or 80-something percent. The more variations there are, the worse it becomes.
So that’s my two cents. Do you agree? Again, lovely article… (We just differ on one small detail.)
Gordon wrote:
Wonderful article, and you are right FUD was stopping. No more!
Thanks for taking the time to capture this info, it’s people like you that help people like me look good (well.. better at least..)
Mike P. wrote:
James, I believe that 76% came from Owen Briggs work:
http://www.thenoodleincident.com/tutorials/box_lesson/font/
Shawn Medero wrote:
My own testing tells me 76% is as small as you can go before things text becomes unreadable in some browsers.
ie wrote:
An excellent article. I think I finally understand how to make ems work.
Nonetheless, the em approach seems to me to be fairly unwieldy. I differ with you that “sizing with keywords is more complicated.” The ALA article you’re alluding to was the first of its kind. Things have moved on since.
The technique has stood me in good stead many a time.
body, div, table, h1, ... h6 {
font-size: x-small; fot-size: small; /* ALA uses Celik’s hack, I prefer Tan’s hack */
}
This gives you a “base” font size 13px in all major browsers if and when set to “medium” text size. Now you can alter text size using either ems or percentages without a usual ripple effect or tedious calculations.
When you size text, let’s say, from smallest to largest in IE, it’s always legible. See www.stopdesign.com
With ems you may get horrific text size. See www.micr.cz
patrick h. lauke wrote:
two issues that are worth mentioning as well:
– IE gets its text resizing horribly wrong when just using ems. if your text size is set to normal, it’s fine, and ems relate directly to what the equivalent percentage would be…so having 0.75em on the body would have the same effect as 75%. now, bump the text size up or down, and you’ll notice that IE scales ems far more drastically than percentages, resulting in too big / too small text. the deceptively simple solution: in addition to having something likebody { font-size: 0.75em; }
you need to add an extra rule (i usually do it on the html) in percentages, which helps IE get its bearing back in terms of resizing…so
html { font-size: 100%; /* IE hack */ }
body { font-size: 0.75em; }
now resizing works consistently.
– although, as per the cascade, setting the font-size on the body should really influence all text sizing in the document, IE seems to ignore it when it encounters a table. the naive approach would be to set the font size for both body and tables like sobody, table { font-size: 0.75em; }
this works in IE, but any other same browser will honour the cascade, resulting in table text actually being sized to 0.75 of 0.75 = 0.5625em. the solution, similar to the previous one, is to add a percentage size to the table
body { font-size: 0.75em; }
table { font-size: 100%; /* IE hack */ }
i seem to remember that this same issue happens with selects and inputs as well, and can be solved in exactly the same way, by adding a 100% sizing to them in the CSS.
i like to call these the “be patronisingly over-specific, so IE knows what you mean” rules…and the beauty is that these don’t break in other browsers, and – apart from being “obvious” – don’t really fall under the category of hacks per se, as they don’t rely on bugs in any browser’s css parsing like, say, the box model hack does…