Apache DevCenter

oreilly.comSafari Books Online.Conferences.

We've expanded our LAMP news coverage and improved our search! Search for all things LAMP across O'Reilly!

Search
Search Tips

advertisement

Listen Print Discuss Subscribe to Apache Subscribe to Newsletters

Simplify Your Life with Apache Virtual Hosts
Pages: 1, 2

vhost Configuration

Let's look at Apache's vhosts settings. We'll use the second scenario first since it's simpler. As a matter of good form, vhost blocks and related directives should go at the end of the httpd.conf file. Below is a minimal configuration for the two virtual hosts:



Listen 80
NameVirtualHost *

<VirtualHost *>
   ServerName www.somesite.com
   DocumentRoot /var/www/parent
</VirtualHost>

<VirtualHost *>
   ServerName www.somesubsidiary.com
   DocumentRoot /var/www/subsidiary
</VirtualHost>

First the port is established to which Apache will listen for requests. Next is a declaration that Apache is to accept virtual host requests on all (*) of the server's IP addresses and default ports; in this case, only port 80. If the server has a few IP addresses, and we only wanted to allow vhost traffic on one IP address, just the permitted address could be specified. Likewise, a specific port could be given to limit traffic further.

NameVirtualHost 10.1.1.50:80

The asterisks inside of the VirtualHost tags can also be changed to the same IP address. It could contain a domain name, instead, but it's not advisable as it adds another layer to start up and can cause a security hole. Apache can have more than one NameVirtualHost directive, and it can have VirtualHost directives with IP addresses not tied to a NameVirtualHost directive. Virtual hosts that are associated with a NameVirtualHost directive by way of the same IP address (including when both use *) are considered to be name-based vhosts; it is the virtual servers' names that distinguishes them. vhosts that specify IP addresses and don't have a complementary NameVirtualHost directives are said to be IP-based vhosts. Apache can have all name-based vhosts, all IP-based vhosts, or a mixture. For our purposes, name-based vhosts are best.

Apache needs to be restarted in order for changes to httpd.conf to take effect. To regenerate the vhost table, service httpd restart usually works on Linux. killall -HUP httpd is a good standby. Regarding the domain names themselves, although the server, prior to hosting the subsidiary's site, did not have a vhost block for the parent company's domain, it must have one now. And to implement a new domain for the subsidiary, the new domain must be registered and set up in DNS, either on the server if it's a registered name server, or with the ISP. With a leased virtual server, the web hosting company needs to add the new domain to their DNS.

In summary, with vhost settings in Apache, the systems administrator will be able to host both domains on his existing server. It requires very little reconfiguring and she will save a great deal of time and expense by not having to set up a new server.

Local Configuration

Returning to the first scenario one, the vhost configuration will need to be changed a bit.

Listen 80
NameVirtualHost 127.0.0.1

<VirtualHost 127.0.0.1>
   ServerName localhost
   DocumentRoot /var/www
</VirtualHost>

<VirtualHost 127.0.0.1>
   ServerName local-client_a.com
   DocumentRoot /var/www/client_a
</VirtualHost>

<VirtualHost 127.0.0.1>
   ServerName local-client_b.com
   DocumentRoot /var/www/client_b
</VirtualHost>

The NameVirtualHost directive has changed from all IP addresses of the workstation to only the local, loopback address. This will make client files accessible only locally . While the second and third vhost blocks are for client files, the first and default block is for a menu page (another index.html) that will be placed in the /var/www directory:

<html>
<body>
<h2>Client Sites</h2>
    <table width='300' border='0'>

    <tr><td width='125'>Client A:</td>
    <td><a href='http://local-client_a.com'>Local</a>;</td>
    <td><a href='http://www.client_a.com'>On-Line</td></tr>

    <tr><td width='125'>Client B:</td>
    <td><a href='http://local-client_b.com'>Local</a>;</td>
    <td><a href='http://www.client_b.com'>On-Line</td></tr>

</table>

</body>
</html>

This plain web page provides an opening menu when the developer enters http://localhost/ into his browser. By clicking on a link, Apache will feed him the local or the remote copy of index.html for the client he selects. This requires the local client domains to be entered into his /etc/hosts file:

127.0.0.1	localhost
127.0.0.1	local-client_a.com
127.0.0.1	local-client_b.com

All of these entries could go on one line, without repeating the localhost address, though it's more manageable with one client per line.

Local Processing

Let's apply the earlier process analysis to the local vhost configuration. When the developer enters http://local-client_a.com/cgi-bin/search.cgi in his browser (or clicks on a link from Client A's index page locally to /cgi-bin/search.cgi), per /etc/host.conf, it will check /etc/hosts before asking a public DNS server to translate the domain to an IP address. It will discover that local-client_a.com is 127.0.0.1 and will therefore send the request with an HTTP host header to that local address, to Apache. Looking in Apache's access log (/var/log/httpd/access_log) we can see what was received:

127.0.0.1 - - [01/May/2003:21:16:04 -0500] 
	"GET /cgi-bin/search.cgi HTTP/1.1" 200 843 "http://local-client_a.com/"
	"Mozilla/4.0(compatible;MSIE 5.0;Linux 2.4.20-2.48 i686)Opera 6.11[en]"

Apache then looks up 127.0.0.1 in its vhost address sets table and finds three vhosts associated with the address. It then scans for a ServerName in order of entry that matches local-client_a.com. If it fails to find a match, it will go back to the first entry for 127.0.0.1 (localhost) and use it. It does, however, find a match with the second vhost, so it looks in that vhost's root directory (/var/www/client_a) for the subdirectory cgi-bin and the file search.cgi within it. The result is that links that work on the client's site now work locally.

Other Directives

Just about any main server directive can be added to a vhost block. These are a few in particular that I have found to be handy:

Logs

Apache is usually set to record messages in the error_log and the access_log files located in /var/log/httpd. However, you may want each virtual host to have its own logs. Add the following to a vhost block to change its log settings:

ErrorLog /var/log/httpd/client_a-error_log common
CustomLog /var/log/httpd/client_a-access_log common

Of course, you'll have to create the new log files, too. They're plain text files and can be created with the touch command:

touch /var/log/httpd/client_a-error_log

Be sure to change the permissions and ownership appropriately. Depending on your configuration, these commands may resemble:

% chmod 644 client*
% chown apache:apache client*

Errors

You can insert these next two lines into a vhost block to direct Apache to display customized error messages to the user.

ErrorDocument 404 /messages/404.html
ErrorDocument 500 /messages/500.html

Here Apache is told that the error messages are located in /messages. Again, you'll have to create the files as well as the directory specified. Error 404 is for files not found; error 500 is for internal server errors — these occur when scripts fail.

Redirecting

On a site that I've administered for over four years now, we used to have hundreds of flat HTML pages. A year ago we moved all of the content to a MySQL database and I wrote some Perl scripts that retrieve and display the data as users request it. Unfortunately, when users come to the site from a search engine with old data, they sometimes are looking for an HTML page that no longer exists. A simple fix that I've used for this is the RedirectMatch directive.

RedirectMatch permanent .html /cgi-bin/index.cgi

This directive, located inside of the vhost block, redirects clients who are looking for pages ending in .html to the main script. This is much nicer than displaying an error message.

Related Reading

Apache: The Definitive Guide
By Ben Laurie, Peter Laurie

ServerAlias

If you have a vhost that you would like to use for more than one domain name, then you can put a ServerAlias directive inside of the vhost block to link the two domain names together.

ServerAlias somesite.com secondsite.com

Subdomains

I have some clients that use subdomains. For instance, they have sales.somesite.com for a somewhat separate web site for their sales department. There's no special directive for this situation. Just set up one vhost block for the main domain (ServerName www.somesite.com) and another vhost block for the subdomain (ServerName sales.somesite.com), with a different directory for the DocumentRoot.

Closing Recommendations

Configuring Apache for virtual hosts is pretty simple, but you can run into problems if you're not sure of the settings or understand the concepts of the essential directives. For further reading, Apache: The Definitive Guide (O'Reilly 2003) now has a chapter on virtual hosts, and there's the Apache site's on-line vhosts documentation. If you have problems, you can always ask for help on a Usenet forum like comp.infosystems.www.servers.unix. However, as with many things in computers, only add or change the basics, initially. Once you have virtual hosting working, then start adding other directives. Most importantly, though, don't be afraid to consider reconfiguring Apache when faced with a problem with your web site. Just make a backup of the httpd.conf file before experimenting.

Russell Dyer has worked full-time for several years as a free-lance writer of computer articles, primarily on MySQL.


Return to Apache DevCenter.


Have a question about configuration? Ask Russell here.
You must be logged in to the O'Reilly Network to post a talkback.
Post Comment
Full Threads Oldest First

Showing messages 1 through 11 of 11.

  • Virtual hosts
    2005-10-05 19:27:15  dgparent [Reply | View]

    No matter how I seem to configure this both hosts end up at the same web page here is what I have , one is a domain theparents.net nad the other is dgftaworld.net:

    NameVirtualHost *:80

    <VirtualHost *:80>
    ServerName www.theparents.net
    DocumentRoot "F:/Program Files/Apache Group/Apache2/htdocs"
    </VirtualHost>


    <VirtualHost *:80>
    ServerName www.dgftaworld.net
    DocumentRoot "F:/Program Files/Apache Group/Apache2/htdocs/store"
    </VirtualHost>
  • WHY DOESN'T IT WORK??!!
    2005-08-11 20:51:16  Breklin [Reply | View]

    Hi, I am frustrated beyond all...

    I found your excellent tutorial but perhaps I am missing something...

    I have made the mods to my httpd.conf file as you recommend but still cannot get my virtual hosts to work.

    here is the code i have inputted into apache:


    <VirtualHost *:80>
    DocumentRoot /www/breklin
    ServerName loc-breklin.com
    ServerAlias www.loc-breklin.com
    ServerAdmin webmaster@breklin.com
    HostNameLookups off
    <Directory "${path}/www/breklin">
    Options All
    AllowOverride All
    Order allow,deny
    Allow from all
    </Directory>
    </VirtualHost>



    Is there a configuration I am not setting right somewhere above this?

    Please help.

  • Thanks!!
    2004-08-17 17:28:42  kopetzkr [Reply | View]

    I had a gigantic mess going while trying to setup a new customer for web hosting. I have only been an ISP for a year and had never set one up. Your instructions worked PERFECTLY!!

    Thanks a million!!
  • Problem with virtual host
    2003-12-26 01:14:51  anonymous2 [Reply | View]

    I have dynamic ip and update the DNS settings through zoneedit.com. Im hosting 3 sites inside my linux server and the apache conf file as below :

    <VirtualHost *:80>
    ServerAdmin admin@mycichlids.org
    DocumentRoot "/home/mycichlids/public_html"
    ServerName mycichlids.org
    ServerAlias mycichlids.org www.mycichlids.org
    ErrorLog logs/mycichlids.org
    CustomLog logs/mycichlids.org common
    </VirtualHost>

    <VirtualHost *:80>
    ServerAdmin clanx@hafizonline.net
    DocumentRoot "/usr/local/apache/www/mambo"
    ServerName hafizonline.net
    ServerAlias hafizonline.net www.hafizonline.net
    ErrorLog logs/hafizonline.net
    CustomLog logs/hafizonline.net common

    <Directory "/usr/local/apache/www/mambo">

    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all

    </Directory>

    </VirtualHost>

    <VirtualHost *:80>
    ServerAdmin nexon@nexon-solution.com
    DocumentRoot "/home/nexon/public_html"
    ServerName nexon-solution.com
    ServerAlias www.nexon-solution.com
    ErrorLog logs/nexon-solution.com
    CustomLog logs/nexon-solution.com common

    <Directory "/home/nexon/public_html">

    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all

    </Directory>
    </VirtualHost>

    The problem im countering is sometimes the web pages is does not point to the actual documentroot. Let say If i want to browse hafizonline.net it goes to mycichlids.org. It happens also to other site nexon-solution.com. Its seems sometimes, the server is mess up and dont know which documentroot it should grap.
    • Problem with virtual host
      2004-12-09 15:58:19  dmoola [Reply | View]

      was this ever resolved? i'm having the same issue.
  • Basic question?
    2003-08-02 11:26:53  anonymous2 [Reply | View]

    I have a low hit server that I use for business as an electronic resume and client file transfer site. Reading about virtual hosts made me think about setting up a vhost solely to serve pictures for my eBay auctions. (I don't like how they format them.) Simple enough. I've got my vhosts up and running. What I'd like to do is make it so that, if someone gets tricky and sends the ip address instead of the domain name, they don't get my business site which has my name, address, and phone number. Since I don't want potential thieves to know where they can find the items I'm selling, how do I structure my httpd.conf and virtual hosts so that my business site doesn't show up when only the ip address is entered?

    I'm a civilian who likes to tinker, not a grisled Apache veteran. So, patience is appreciated.

    Evans
    • Figured it out
      2003-08-02 12:23:50  anonymous2 [Reply | View]

      I moved my photo virtual host up to the top of the list of vhosts. Now, when I directly access my site by ip, I get the blank page I wanted.

      Evans

      PS It's funny how asking for help is a key component for discovering the solution myself.
  • samle virtual host folder structure
    2003-07-28 18:48:57  bjarnedm [Reply | View]

    % ls -aloF
    drwxr-xr-x 8 amalie www - 272 Jul 25 22:52 ./
    drwxr-xr-x 8 amalie www - 272 Jul 25 22:52 ../
    drwxr-x--- 4 amalie www - 136 Jul 18 15:21 Documents/
    drwxr-x--- 2 amalie www - 68 Jul 18 14:35 cgi-bin/
    drwxr-xr-x 6 amalie www - 204 Jul 18 15:33 logs/
    drwxrwx--- 2 amalie mysql - 68 Jul 18 14:35 mysql/
    drwxr-x--- 2 amalie www - 68 Jul 18 14:35 php-includes/
    drwxr-x--- 2 amalie www - 68 Jul 18 14:35 php-sessions/
  • sample virtual host configuration file
    2003-07-28 18:45:31  bjarnedm [Reply | View]

    I like to completely separate my virtual hosts from each others, so I can move a complete directory around without worrying that much, so my standard configuration looks something like this:

    <VirtualHost *>
    ServerAdmin webmaster@virtual-host.net
    ServerName www.virtual-host.net
    ServerAlias virtual-host.net
    DocumentRoot /Volumes/WebServer/virtual-host/Documents
    <Directory "/Volumes/WebServer/virtual-host/Documents">
    Options None
    AllowOverride All
    Order allow,deny
    Allow from all
    </Directory>
    ScriptAlias /cgi-bin/ "/Volumes/WebServer/virtual-host/cgi-bin/"
    ErrorDocument 404 /messages/404.html
    php_value include_path ".:/Volumes/WebServer/virtual-host"
    php_value session.cookie_domain "virtual-host.net"
    php_value session.save_path "/Volumes/WebServer/virtual-host/php-sessions"
    php_value session.use_only_cookies "1"
    ErrorLog "/Volumes/WebServer/virtual-host/logs/error_log"
    CustomLog "/Volumes/WebServer/virtual-host/logs/referer_log" referer
    CustomLog "/Volumes/WebServer/virtual-host/logs/agent_log" agent
    CustomLog "/Volumes/WebServer/virtual-host/logs/access_log" common
    </VirtualHost>

    I also set several php values. The reason for the php-includes directory being the folder containing the virtual host is that sometimes I want to keep the php-includes completely outside of the Documents folder for security reasons, and at other times I want them to be located close to where they are used.
  • separate files for each virtual host
    2003-07-28 18:30:18  bjarnedm [Reply | View]

    I'm on Mac OS X. At the end of httpd.conf I've got these two lines:
    # Include /private/etc/httpd/users
    Include /Volumes/WebServer/virt-hosts

    The first is a standard one the comes with the Apple httpd.conf and the second one is one I doctored myself.
    The upshot of these is that the files in the directories mentioned is read as extensions to httpd.conf. This makes it possible to create a special file for each virtual host, so you only just need to edit single files in this directory instead of having the whole httpd.conf loaded. Additionally, by using virtual links you can give your clients read-only access or possibly even modification rights on their own httpd.conf settings. This isn't much of a security problem as Apache has to be restarted in order for any client modification to be activated.
    • separate files for each virtual host
      2003-08-03 09:32:55  anonymous2 [Reply | View]

      How is this not a security problem? There are plenty of nasty things a joe schmo user can do if he were to have access to his own Apache configuration file.

      Dismissing this a security problem seems to suggest that you will monitor those configuration files at all times, don't you think this just a tad impractical?


Tagged Articles

Post to del.icio.us

This article has been tagged:

apache

Articles that share the tag apache:

Multiuser Subversion (38 tags)

Introducing LAMP Tuning Techniques (32 tags)

Apache Web-Serving with Mac OS X: Part 1 (26 tags)

Introducing mod_security (25 tags)

Location, Location, Location: Tips for Storing Web Site Files (22 tags)

View All

virtual

Articles that share the tag virtual:

How to Publish Multiple Websites Using a Single Tomcat Web Application (6 tags)

Simplify Your Life with Apache Virtual Hosts (3 tags)

Virtual Hosts, mod_rendezvous_apple, and Apache on Mac OS X (2 tags)

A Day in the Life of #Apache (2 tags)

VPN on Mac OS X (2 tags)

View All

howto

Articles that share the tag howto:

Rolling with Ruby on Rails (258 tags)

From Weblog to CMS with WordPress (98 tags)

Top Ten Digital Photography Tips (92 tags)

Top Ten Mac OS X Tips for Unix Geeks (79 tags)

View All

hosts

Articles that share the tag hosts:

Simplify Your Life with Apache Virtual Hosts (2 tags)

View All

virtualhosts

Articles that share the tag virtualhosts:

Simplify Your Life with Apache Virtual Hosts (2 tags)

View All

Sponsored Resources

  • Inside Lightroom
Advertisement

Sponsored by:

O'Reilly Media

©2009, O'Reilly Media, Inc.
(707) 827-7000 / (800) 998-9938
All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.
About O'Reilly
Academic Solutions
Authors
Contacts
Customer Service
Jobs
Newsletters
O'Reilly Labs
Press Room
Privacy Policy
RSS Feeds
Terms of Service
User Groups
Writing for O'Reilly
Content Archive
Business Technology
Computer Technology
Google
Microsoft
Mobile
Network
Operating System
Digital Photography
Programming
Software
Web
Web Design
More O'Reilly Sites
O'Reilly Radar
Ignite
Tools of Change for Publishing
Digital Media
Inside iPhone
O'Reilly FYI
makezine.com
craftzine.com
hackszine.com
perl.com
xml.com

Partner Sites
InsideRIA
java.net
O'Reilly Insights on Forbes.com