Enabling Virtual Hosts on MacOS X
As a web developer, it's not unusual to have a multiple sites under development at the same time. Here's how to develop as many sites as you want, with "root relative" calls for graphics, scripts, CSS, links, etc. and keep all of the files for any particular site together - and they don't even have to be in the default web server document root.
The term Virtual Host refers to the practice of maintaining more than one server on one machine, as differentiated by their apparent hostname. For example, it is often desirable for companies sharing a web server to have their own domains, with web servers accessible as
www.company2.com, without requiring the user to know any extra path information.
Apache was one of the first servers to support IP-based virtual hosts right out of the box. Versions 1.1 and later of Apache support both, IP-based and name-based virtual hosts (vhosts). The latter variant of virtual hosts is sometimes also called host-based or non-IP virtual hosts.
The instructions for adding Virtual Hosts in the Apache documents tell you what you need to change in your Apache configuration - but, they don't give you the rest of the story. To create functioning Virtual Hosts for development on your Mac, you also need to tell it that
http://my.test.site resolves to 127.0.0.1 (the internal IP address of your machine - every machine on the net thinks it is 127.0.0.1) or
http://localhost/. You fix this up by using Apple's NetInfo Manager (Applications/Utilities/NetInfo Manager).
NB: from here on out, you'll have to have administrator privileges on your machine. You don't need to be root, but you do need to have the ability to "sudo".
First, we need to create the pointer to localhost that we're going to use to tell Apache what files to serve as the web site.
- Open NetInfo Manager and browse to /machines/localhost.
- Click on the lock, and enter your password so that you can make changes.
- Duplicate "localhost" (Edit::Duplicate)
- Select "localhost copy" and then select the name property in the lower window
- Change the value of "name" from localhost to whatever your development site will be. Remember, if you choose a real domain, you won't be able to do anything (like see the web site, send mail, etc.) with that domain from this machine. I use bogus TLD's - so www.test.site works fine.
- Click on one of the other directories in the list, and you will be asked if you want to save your changes. Save them!
You've now made an entry in your NetInfo Manager for a bogus site that points to your local machine. If you try to go to http://www.test.site now with a web browser, you'll see the same thing you'll see if you go to http://localhost/. Which brings us to step two - creating the vhost entry in the Apache Config file.
Open Terminal and enter:
[localhost:~] bob% cd /etc/httpd/
[localhost:/etc/httpd] bob% ls -la
One of the files you see in there should be httpd.conf. You'll want to make a backup of that file - just in case. So...
[localhost:/etc/httpd] bob% cp httpd.conf httpd.conf.back
[localhost:/etc/httpd] bob% ls -la
Now you see httpd.conf and httpd.conf.back in the directory.
Now comes the fun part. You need to edit your httpd.conf file. Since it is owned by root and root is the only user with read and write permissions on the file, you will need to pretend that you are root, even if it's just for a little while. The safest way to do this is to use the "sudo" command. In the next examples, I use emacs to edit the httpd.conf file, but you also have vi and pico at your disposal, and you can use TextEdit or BBEdit if you like. I only use emacs because it's what I know and I like the safety of not having an application opened as root (which is what you'd get if you used open -a and used BBEdit or TextEdit).
So, issue the following command:
[localhost:/etc/httpd] bob% sudo emacs httpd.conf
Find the line (ctrl + s to search in emacs) that reads
### Section 3: Virtual Hosts and read the description below it. It shows an example of a name based vhost. Uncomment the line that reads
#NameVirtualHost * and change it to
NameVirtualHost 127.0.0.1. Below the example VirtualHost, you'll want to create your own listings now.
If you tell the server that you have one vhost on 127.0.0.1, it will presume that every call to 127.0.0.1 (including localhost) is a request for that web site - so, if you want to have http://localhost work, you need to add 2 vhost entries. It looks like this:
# Leave this one alone - it makes sure that localhost works. <VirtualHost 127.0.0.1> DocumentRoot /Library/WebServer/Documents ServerName localhost </VirtualHost> # Add new hosts here for development <VirtualHost 127.0.0.1> DocumentRoot /Library/WebServer/Documents/path/to/files ServerName www.test.site </VirtualHost>
In the listing for your test site, you can make the DocumentRoot value whatever you want. It doesn't have to be in the default web docs directory. Whatever will work for you to help you keep your files in order is fine.
Save your changes (ctrl+x, ctrl+s) and quit emacs (ctrl+x, ctrl+c). Now you have to restart Apache. In MacOS X, the easiest way to do this is in the Sharing panel in System Preferences. Turn Web Sharing off, then turn it on again. It's that simple.
Now, open a web browser and go to http://www.test.site/. If you've done it all right, you'll see the site you pointed at in the httpd.conf file. All of your root relative calls will work, and all of your files are manageable again. As you pick up new sites to build, you can easily add them like this and have a complete testing and development machine.