Apache DevCenter
oreilly.comSafari Books Online.Conferences.


Apache Cookbook

A Day in the Life of #Apache
Configuring Virtual Hosts

by Rich Bowen, coauthor of Apache Cookbook

Editor's note: Rich Bowen, coauthor of Apache Cookbook, spends a lot of time fielding questions on the IRC channel, #apache. In the inaugural article to launch this new series based on those conversations, Rich provided a solution to a user's troubles getting his .htaccess file working. In this installment, Rich tackles configuration issues in the sometimes bewildering world of virtual hosts.

#apache is an IRC channel that runs on the irc.freenode.net IRC network. To join this channel, you need to install an IRC client (XChat, MIRC, and bitchx are several popular clients, although there are roughly three bzillion other ones, too) and enter the following commands:

/join #apache

Day Two

Welcome to another day on #apache. Perhaps the most frequent topic that we encounter on #apache is virtual hosts. Yes, an enormous amount of content has been written about virtual hosts. I think they are probably the most documented feature of Apache. But people still have problems with them. Part of this is that some of the documentation is confusing. And part of it is that virtual hosts themselves are confusing, and tend not to work the way that people expect them to.

In today's #apache conversation, we'll see some of the most frequent misunderstandings, as well as a few of the more common virtual host misconfigurations.

But, before we get started, I feel the need to rant just a little bit. This is not exclusively self-indulgent. It will be relevant in a moment.

I hate the word virtual. Passionately. I always have. Why? Well, because it doesn't mean anything at all. It used to mean something. The Middle English roots refer to something possessing certain virtues, and so in modern English, it refers to something which possesses the qualities of something, but is not that thing. So, presumably, a virtual host is kind of like a real host, only ... not.

Related Reading

Apache Cookbook
By Ken Coar, Rich Bowen

But, then came the '90s, and everything was virtual. Virtual pets. Virtual money. Virtual girlfriends. Virtual intelligence. Of course, then there was "cyber." Don't get me started.

So, whenever possible, I try to avoid using the term virtual, except when it is completely unavoidable. And, alas, when discussing virtual hosts, it's unavoidable. *sigh*

OK, I'm done ranting. I feel much better now.

I should also note, however, that when I asked for peer review of this article, a delightful discussion ensued regarding the word "virtual" and whether it had useful meaning. Which, of course, it does. I'm overdramatizing. So, I should relay to you:

<niq> "irc is the virtual coffee machine"
<niq> ... as in, the coffee machine is said to be the most productive place in an office, with a stimulating exchange of ideas between coworkers.

All right. On with the show. (And for newcomers to this column, I play DrBacchus on the show.)

-->b3g1nn3r has joined #apache
<b3g1nn3r> Is anybody here?
<fajita> Just us chickens.
<b3g1nn3r> No matter which virtual host I visit, I keep getting the same one.
<DrBacchus> Is it the first one listed in your configuration file?.
<b3g1nn3r> Yes, it's the first one. The other ones I have configured never show up.
<DrBacchus> Are you doing name-based or IP-based virtual hosting?
<b3g1nn3r> Name-based.
<DrBacchus> post config
<fajita>Please put your configuration file on your web site so that we can have a look at it. Or See 'nopaste' if you don't have access to a place to upload.
<b3g1nn3r> nopaste?
<fajita> nopaste is http://nopaste.snit.ch/ or http://pastebin.com/

People on IRC have a real thing about pasting large blocks of text. It's hard to read them when they're interspersed with ongoing conversation, and they scroll away before you can get a good look at them. So, if you need to have people look at something, it is best to post that content to your web site, or use one of the many paste servers that are out there specifically for this purpose.

In this little exchange you'll also see another strange thing about IRC. Folks rely heavily on the bot. When a particular phrase is often repeated, there will usually be a shortcut. So, rather than uttering a complete sentence like a civilized person, the bot allows me to grunt out partial phrases, and have fajita fill in the blanks for me. Yet another example of how technology makes us dumber.

So, at this point in the conversation, b3g1nn3r goes off and puts his configuration file on his web site -- presumably in the functioning virtual host -- and then tells us the URL for that file. Looking at it, we find something like this:

<VirtualHost larry.veggie.com>
  DocumentRoot /home/larry/www
  ServerName larry.veggie.com

<VirtualHost bob.veggie.com>
  DocumentRoot /home/bob/www
  ServerName bob.veggie.com

There are several problems with this configuration, which we'll try to address, leaving b3g1nn3r with a functioning virtual host configuration.

First, when doing name-based virtual hosting, you must have a NameVirtualHost directive, telling Apache which interface to listen to for name-based virtual host requests. This directive can take one of three forms:


Or ...


Or ...

NameVirtualHost *:80

If you have only one IP address, you should probably end up using the *:80 syntax, but it's useful to know what the other two syntaxes are for.

The first syntax tells Apache to listen on the specified interface, on all available ports. In this case, "all available ports" will mean whatever ports for which there is a Listen directive somewhere.

The second syntax is similar, but limits the vhosts to a particular port. This is particularly useful if you want to run different vhosts on different Ports; for example, when you're running an SSL web site. You'll notice that the default Apache configuration file prefers this syntax, in order to specify that the example vhosts are only for port 80.

Finally, the *:80 syntax indicates that the vhosts will be on all interfaces, on the specified port. This is the simplest syntax for most people. It also has the added advantage that it works for people with dynamic IP addresses, and allows you to move sites from one server to another without having to change the configuration.

Oh, and you can also use * to specify all interfaces, all ports, but you should be aware that if you do happen to run a host on another port, or, perhaps, an SSL site, this can cause some conflicts, since the "all ports" virtual host may take precedence.

Second, you need to makes sure that the argument to VirtualHost matches the argument to NameVirtualHost. In the configuration example given to us, the name of the virtual host was used on the <VirtualHost> declaration. In fact, you should generally use the IP address. The server name is specified by the ServerName directive. Hence the clever name.

The first-listed virtual host is always the default. That is to say, if Apache receives a request for any virtual host for which it does not have an explicit virtual host declaration, it will display whatever host is defined in that first VirtualHost section.

So, we might rewrite the configuration for b3g1nn3r's virtual hosts as follows:

NameVirtualHost *:80

<VirtualHost *:80>
  DocumentRoot /home/larry/www
  ServerName larry.veggie.com

<VirtualHost *:80>
  DocumentRoot /home/bob/www
  ServerName bob.veggie.com

But, alas, there's still a problem.

<b3g1nn3r> Well, now those two vhosts work, but now I can't get to my main host!

And so we come back to my little rant at the beginning. You see, there's nothing virtual about virtual hosts. Not only are they just as real as the main host, it turns out that they are more real than the main host.

<DrBacchus> main host goes away
<fajita> main host goes away is http://httpd.apache.org/docs-2.0/vhosts/name-based.html#using (See note about "Main host goes away")

And, the documentation that fajita has pointed us to says the following:

If you are adding virtual hosts to an existing web server, you must also create a <VirtualHost> block for the existing host. The ServerName and DocumentRoot included in this virtual host should be the same as the global ServerName and DocumentRoot. List this virtual host first in the configuration file so that it will act as the default host.

So, as mentioned above, the first-listed virtual host is now the default host, and the server defined outside of the virtual-host blocks has become completely invisible. In order to get that "main" host back, you have to define it as a virtual host. Once you start using virtual hosts, everything is a virtual host. Which is to say, it's not virtual at all.

At this point, we probably have a happy Apache administrator, and he or she thanks us profusely and goes on his or her way.

<b3g1nn3r> Thanks, fajita!
<fajita> my pleasure, b3g1nn3r
<-- b3g1nn3r has quit (connection reset by beer)

If you want to read more about virtual hosts, the place to start is in the main virtual host documentation:

<DrBacchus> vhosts?
<fajita> vhosts is http://httpd.apache.org/docs-2.0/vhosts/ or http://httpd.apache.org/docs/vhosts/

There you will find descriptions of how they work, copious examples of common configurations, and explanations of the different types of virtual hosts. What we've seen here is the most common scenario, but by no means the only one.

Stay tuned. Next month we'll tackle another common Apache dilemma.

Rich Bowen is a member of the Apache Software Foundation, working primarily on the documentation for the Apache Web Server. DrBacchus, Rich's handle on IRC, can be found on the web at www.drbacchus.com/journal.

O'Reilly & Associates recently released (November 2003) Apache Cookbook.

Return to Apache DevCenter.

Sponsored by: