How to Test Multiple Websites on One PC With Apache Virtual Hosts

Contributing Editor

Run multiple sitesIt is rare to find a web developer with responsibility for just one website. In this article, we will configure your development PC so you can test any number of websites using a dedicated domain name for each one. You will require a local installation of Apache 2.2 and, optionally, PHP and MySQL.

The Heavenly Hosts File

When you enter an address in your browser, the domain name is normally converted to an IP address by a domain name server. Just prior to that, the computer will check its own hosts file. Host files are available on nearly every operating system:

  • Windows NT, 2000, XP, 2003 and Vista: %WinDir%system32driversetchosts (note this location can be changed in the registry key HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParametersDataBasePath)
  • Windows 95, 98, ME: %WinDir%hosts
  • Linux, Unix, BSD: /etc/hosts
  • Mac OS X: /private/etc/hosts

In most cases, your hosts files will contain a single entry:


127.0.0.1  localhost

Entering ‘http://localhost/’ in your browser will resolve to the TCP/IP loop-back address 127.0.0.1 (your PC).

The hosts file can contain any number of domain mappings. Assume we want to test two sites locally: www.mysite1.com and www.mysite2.org. We can create two domains in our hosts file for testing purposes, e.g. mysite1 and mysite2:


127.0.0.1  localhost
127.0.0.1  mysite1
127.0.0.1  mysite2

Some operating systems will implement the change as soon as the hosts file is saved. Windows users should enter “nbtstat -R” at the command line. Try a reboot if all else fails.

Configuring Apache Virtual Hosts

Apache can run any number of websites on a single machine. (Note: so can the server versions of Microsoft IIS, but not the Windows Professional or VisualStudio.NET editions).

Shut down Apache and load its configuration file, confhttpd.conf, in a text editor. Assuming we want the domain mysite1 to use the files in D:WebPagesmysite1 and mysite2 to use the files in D:WebPagesmysite2, we would add the following Virtual Host definitions to the bottom of the file:


# Virtual hosts
NameVirtualHost *:80

# Any unspecified domain
<VirtualHost *:80>
	DocumentRoot D:/WebPages
</VirtualHost>

# mysite1 domain
<VirtualHost *:80>
	ServerName mysite1
	DocumentRoot D:/WebPages/mysite1
</VirtualHost>

# mysite2 domain
<VirtualHost *:80>
	ServerName mysite2
	DocumentRoot D:/WebPages/mysite2
</VirtualHost>

Save the file and restart Apache.

Testing Your Sites

Copy your website files to D:WebPagesmysite1 and D:WebPagesmysite2 accordingly. You can now enter either http://mysite1/ or http://mysite2/ in your browser to test the appropriate site.

Bonus tip for PHP coders
It can be useful to know whether the site is running on the live or development environment, e.g. debugging messages are not shown on the live site. You can detect the domain using code such as:


<?php
$debug == ($_SERVER['HTTP_HOST'] == 'mysite1');
if ($debug) echo "debug message";
?>

See also:

Do you have any other tips for testing multiple websites on a single PC?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.cemerson.co.uk Stormrider

    Personally I just use sub folders within my document root folder to differentiate between sites – eg http://localhost/site/httpdocs/ or whatever.

  • ‘Timi

    Is this way similar to setting up sub domains? I mean like:
    ServerName sub.mysite1
    DocumentRoot D:/WebPages/mysite1/sub

  • John Girvin

    Since I tend to work only on one site at a time, I have scripts to start up the correct version of Apache, PHP, MySQL etc. that the site requires (depending on where it will eventually be hosted) and pull in the correct configuration for each. Each project has its own Apache config file which pulls in a master Apache config before applying project specific changes.
     
    In my dev environment for johngirvin.com I have:
    # master configuration
    Include c:/foo/_conf/apache-2.2.08.conf
    Include c:/foo/_conf/php-5.2.6/apache.conf
     
    # project specific configuration
    Listen 80
     
    <VirtualHost *:80>
        DocumentRoot c:/foo/johngirvin.com/trunk/httpdocs/
        …etc.
    </VirtualHost>

     
    In the past I’ve also used one config file with different Listen ports for each VirtualHost, which avoids making any changes to the hosts file and has minimal project specific configuration, but gets unwieldy as the number of hosted sites grows and you have to remember which site lives on which port.
     
    I’ve since found it easier to use the above “layered modular configuration” approach. Furthermore, it permits using different versions of Apache / PHP / MySQL or alternatives (Ruby, Python, PostgreSQL etc.) for different projects on one workstation.
     
    Using NamedVirtualHosts and the hosts file is very usable, but it adds an external dependency for your projects. The best solution, as ever, depends on your needs.

  • http://www.mikedesign.net/ mauteri

    @Stormrider Doesn’t that affect any absolute linking you might want to do (e.g. /includes/foo.php) or calling $_SERVER['DOCUMENT_ROOT']? I think in these situations, having a virtual host would be beneficial.

  • Oluwasogo

    This is nothing but an overkill why do u want to suffer an average developer or a novice developer with all these?? when u can just put ur sites in different folders in the root folder and name them the name of the site….for example…..http://localhost/site1 and http://localhost/site2 and u can continue in this trend till ur hard disk gets full…pleas dont use an axe to cut weed…the job wont be done properly and u end up burning much energy too

  • chodorowicz

    isn’t it better to use the httpd-vhosts.conf file?

  • mr_than

    Been doing it this way for years, it’s the best because you get a proper document root. Add the same hosts entries to a VM and testing IE6 is easy as.

  • planettech9

    Hi dear
    I do agree with you that you think that much about our young generations. I also think the same.I am very happy to get that comment from you .so I am thanking you for giving this wonderful suggestions.
    ===========================
    sameer
    ===========================

    temping jobs-

  • http://art4eye.com -T-

    I never work on more then one site at the time, so I usually just find it easier to change the httproot directory in mamp/wamp (even comes with a nice gui where you can browse to the directory :)

  • Anonymous

    I find it useful to treat the name of sites like a subdomain – http://www.sitename.com becomes local.sitename.com. That way if you are testing things like API keys that are tied to a specific domain, they will also work in the local environment as well as the live production site.

  • http://www.optimalworks.net/ Craig Buckler

    @Oluwasogo

    u can just put ur sites in different folders in the root folder

    And you can still do that. I certainly do for smaller, less complex sites (everything comes off the domain ‘test’).

    However, some applications require installation in the root folder. Some are folder-critical. Some require configuration changes depending on where it’s installed. Having a structure that matches your live environment helps significantly and ultimately requires less maintenance (thanks Anonymous for the local.sitename.com tip – that’s a great idea).

    It’s really up to you whether you do this or not. Everyone’s confused when they first start web development, but novices can progress by understanding techniques such as this. I wish I’d discovered it years before I did.

    @chodorowicz

    isn’t it better to use the httpd-vhosts.conf file?

    It’s really up to you. I personally prefer all the configuration in one file and the example above will also work in older versions of Apache.

    @John Girvin

    Since I tend to work only on one site at a time, I have scripts to start up the correct version of Apache, PHP, MySQL etc. that the site requires (depending on where it will eventually be hosted) and pull in the correct configuration for each.

    I think that’s a great idea if you’re only developing one site, especially since you can match PHP and MySQL versions and configurations.

    I think I’d miss being able to access my other development sites, though. Perhaps running them on different ports would help? e.g. localhost:81, localhost:82, etc. You could still have differing configurations and access all your sites at the same time.

  • http://www.cemerson.co.uk Stormrider

    @mauteri

    Yes, but I never use absolute links in a site. It makes quite a large assumption about where your site will be situated, and it might not be at the top level of a domain in the future, you never know. No point in shooting yourself in the foot.

  • http://www.johngirvin.com johngirvin

    @Craig Buckler

    I think I’d miss being able to access my other development sites, though. Perhaps running them on different ports would help?

     
    No problem: the scripts for each site could easily start their required versions of Apache etc. listening on different ports by pulling in config files customised for each site. You’d need to keep track of which sites use which ports, to avoid clashes.
     
    I find I’m better off concentrating on one site at a time though!

  • markfiend

    I’ve been doing this for ages too, it’s a great way of deploying a *proper* web testing environment (although like chodorowicz I use the httpd-vhosts.conf file).

    It’s definitely worth bringing to people’s attention. Thanks!

  • jspa

    thank , when i get home i’ll try this =)

  • http://www.papayasoft.com/ rundmw

    @Stormrider, @mauteri: Both approaches (relative addressing and root-absolute addressing) make assumptions. Relative addressing assumes a requested resource is in some fixed position relative to the caller. Root-absolute addressing assumes that the requested resource is in some fixed position relative to the root url of the app.

    A discussion of different addressing conventions and their relative (no pun intended, at least initially) advantages/disadvantages is probably worth another post (Hint, hint, Craig).

    I’ve been using virtual hosts as described by Craig for years now and it has been a huge help.

    One other item of note re: hosts file. I was doing some offline web development during a visit to the boondocks during which I had *no* network adapter enabled on my WinXP machine. Even though HOSTS had all my mappings, requests to the named host were coming back unknown, not resolving as expected to the 127.0.0.1. Only when I added the mappings to an lmhosts file (same folder as HOSTS), did the resolution work again.

  • http://www.pcbunk.net XtrEM3

    i appreciate you sharing this and especially the timing, i’ve been working on multiple sites recently and i found many links and references failed to work in subfolders…this is exactly the solution i was looking for! also thanks to whoever suggested the subdomain method of local.mysite.com…excellent solution to separating local from web.

  • timothytrice

    I wrote an article on the same thing a month ago however I don’t suggest going through the Registry as this article does but rather go to the hosts file in the Windows directory. There are too many uninformed readers who will get in there and quite conceivably jack their computer up.

    In reference to those of you who want to use subdirectories for each of your sites…to each his own, I suppose. But see how easy it is when you’re dealing with rather complex applications and transfer them to your live sites. Virtual Hosts makes life so much easier and takes out so much potential confusion.

  • http://www.optimalworks.net/ Craig Buckler

    @timothytrice

    I don’t suggest going through the Registry

    The article doesn’t say that you need to change the registry. It’s saying that the location of the hosts file can be changed. So, if hosts file configuration doesn’t work, check your registry to ensure you’re editing the right file!

  • sw309482

    A better way is to use ports:

    Listen 801
    Listen 802
    Listen 803

    <VirtualHost *:801>
    DocumentRoot "/sites/site01"
    ServerName Site1
    </VirtualHost>

    <VirtualHost *:802>
    DocumentRoot "/sites/site02"
    ServerName Site2
    </VirtualHost>

    <VirtualHost *:803>
    DocumentRoot "/sites/site03"
    ServerName Site3
    </VirtualHost>

  • picohax

    Thanks for this quick tip.
    Although I believe that one could spend a whole week only configuring Apache to do a hundred things with urls, this is a perfect-sized morsel for newbies.
    Small enough to chew and very useful. :-)
    And thanks to the commenters who add their own tweaks!

  • Miked

    Hi there…. this is just what I was looking for.
    One question… if I am using perl etc will it still be http://site1/cgi-bin and so on …. will the scripts still run from there?

    Sorry if thats a stupid question.
    Thanks

  • http://www.optimalworks.net/ Craig Buckler

    Installing Perl is easier than PHP (although I’ve not done it for a little while) and yes, it will work.