Early versions of HTTP (like many other protocols, e.g. FTP) required a different IP address for each virtual host on the server. On some platforms this can limit the number of virtual hosts you can run, and because there are concerns about the availability of IP addresses it is strongly discouraged by the registraries (ARIN, RIPE, and APNIC).
The HTTP/1.1
protocol, and a common extension
to HTTP/1.0
, includes a method for the server to
identify what name it is being addressed as. Apache 1.1 and
later support this approach as well as the old
IP-address-per-hostname method.
The benefits of using the name-based virtual hosts is a practically unlimited number of servers, ease of configuration and use, and it requires no additional hardware or software. The main disadvantage is that the client must support this part of the protocol. Almost all browsers do, but there are still tiny numbers of very old browsers in use which do not. This can cause problems, although a possible solution is addressed below.
Using name-based virtual hosts is quite easy, and
superficially looks like the old method. The notable difference
between IP-based and name-based virtual host configuration is
the NameVirtualHost
directive which specifies an IP address that should be used as
a target for name-based virtual hosts, or the wildcard
*
to indicate that the server only does name-based
virtual hosting (no IP-based virtual hosting).
For example, suppose that both www.domain.tld
and www.otherdomain.tld point at the IP address of
your server. Then you simply add to one of the Apache
configuration files (most likely httpd.conf
or
srm.conf
) code similar to the following:
NameVirtualHost * <VirtualHost *> ServerName www.domain.tld DocumentRoot /www/domain </VirtualHost> <VirtualHost *> ServerName www.otherdomain.tld DocumentRoot /www/otherdomain </VirtualHost>
Of course, any additional directives can (and should) be
placed into the <VirtualHost>
section. To
make this work, all that is needed is to make sure that the
names www.domain.tld and
www.otherdomain.tld are pointing to the right IP
address.
Note: When you specify an IP address in a
NameVirtualHost
directive then requests to that IP
address will only ever be served by matching
<VirtualHost>s. The "main server" will
never be served from the specified IP address.
If you specify a wildcard then the "main server" isn't used at
all. If you start to use virtual hosts you should stop using
the "main server" as an independent server and rather use it as
a place for configuration directives that are common for all
your virtual hosts. In other words, you should add a
<VirtualHost> section for every server
(hostname) you want to maintain on your server.
Additionally, many servers may wish to be accessible by more
than one name. For example, the example server might want to be
accessible as domain.tld
, or
www2.domain.tld
, assuming the IP addresses pointed
to the same server. In fact, one might want it so that all
addresses at domain.tld
were picked up by the
server. This is possible with the ServerAlias
directive, placed inside the <VirtualHost> section. For
example:
ServerAlias domain.tld *.domain.tld
Note that you can use *
and ?
as
wild-card characters.
You also might need ServerAlias
if you are
serving local users who do not always include the domain name.
For example, if local users are familiar with typing "www" or
"www.foobar" then you will need to add ServerAlias www
www.foobar
. It isn't possible for the server to know
what domain the client uses for their name resolution because
the client doesn't provide that information in the request. The
ServerAlias
directive is generally a way to have
different hostnames pointing to the same virtual host.
As mentioned earlier, there are still some clients in use who do not send the required data for the name-based virtual hosts to work properly. These clients will always be sent the pages from the first virtual host listed for that IP address (the primary name-based virtual host).
There is a possible workaround with the ServerPath
directive, albeit a slightly cumbersome one:
Example configuration:
NameVirtualHost 111.22.33.44 <VirtualHost 111.22.33.44> ServerName www.domain.tld ServerPath /domain DocumentRoot /web/domain </VirtualHost>
What does this mean? It means that a request for any URI
beginning with "/domain" will be served from the
virtual host www.domain.tld This means that the
pages can be accessed as
http://www.domain.tld/domain/
for all clients,
although clients sending a Host: header can also
access it as http://www.domain.tld/
.
In order to make this work, put a link on your primary virtual host's page to http://www.domain.tld/domain/ Then, in the virtual host's pages, be sure to use either purely relative links (e.g., "file.html" or "../icons/image.gif" or links containing the prefacing /domain/ (e.g., "http://www.domain.tld/domain/misc/file.html" or "/domain/misc/file.html").
This requires a bit of discipline, but adherence to these guidelines will, for the most part, ensure that your pages will work with all browsers, new and old.
See also: ServerPath configuration example