If you want to easily mirror multiple live websites locally for super fast and offline development, then read on!
When I reinstall OS X, I very quickly reconfigure Apache to allow for local vhosts. Apache can be a bit of a minefield for configuration and I am by no means an expert, however, these simple steps give a huge amount of benefit as you won’t need to edit apache’s configuration files every time you want to add a new vhost.
One example which I use daily is alfredapp.com which is setup locally as alfredapp.localhost – These two sites are exact mirrors of each other both rooted with / can be significant in web development when accessing resources and site links. I can develop and test on the local site, then when I’m happy, push the changes to my distributed repository and deploy to the live site.
Note that the following config changes may mutually exclude any other apache changes you have made… If that means nothing to you, then this will likely work fine.
Before we start, turn on Web Sharing
Open up OS X’s sharing preferences and turn on “Web Sharing”, this will start up Apache.
Step 1 – Backup the configuration files
/etc/apache2/httpd.conf
/etc/apache2/extra/httpd-vhosts.conf
/etc/apache2/users/[username].conf
Step 2 – Import the vhosts config into httpd.conf
Temporarily, we are going to make the httpd.conf writable to make some changes.
Open Terminal.app and type:
sudo chmod u+w /etc/apache2/httpd.conf
Then open the httpd.conf file and remove the # off the beginning of the following line:
#Include /private/etc/apache2/extra/httpd-vhosts.conf
While you are in here and if you haven’t done so already, it’s probably worth also uncommenting PHP too by removing the # from the following line:
#LoadModule php5_module libexec/apache2/libphp5.so
Save your changes and make your mac more secure again by making the httpd.conf file unwritable:
sudo chmod u-w /etc/apache2/httpd.conf
Step 3 – Do some magic in the vhosts config
Replace the contents of /etc/apache2/extra/httpd-vhosts.conf with the following:
UseCanonicalName Off
VirtualDocumentRoot /Users/[username]/Sites/vhosts/%0
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
CustomLog /var/log/apache2/access_log vcommon
Turning off UseCanonicalName makes Apache ignore the ServerName directive and instead use the domain name supplied by the browser to construct the domain (blah blah or something like that). VirtualDocumentRoot sets where Apache looks for the virtual hosts. Replace [username] with your case sensitive usename. The last two lines setup the log format adding the virtual host at the beginning using %V.
Step 4 – Setup the access for vhosts for your user
In my case, edit /etc/apache2/users/preppeller.conf and update the directory access:
<Directory "/Users/[username]/Sites/"> Options Indexes MultiViews FollowSymLinks AllowOverride All Order allow,deny Allow from all </Directory>
Naturally change [username] with your user case sensitive again. Updating this config file firstly allows apache to access this folder, but also allows for better .htaccess overrides.
Step 5 – Restart Apache
In Terminal type:
sudo apachectl restart
Step 6 – How to use… this is the easy part!
Lets say I want to setup alfredapp.localhost. Firstly, I create the following folder in Terminal:
mkdir ~/Sites/vhosts/alfredapp.localhost
This will contain the files for the website (I just grab these out of repository). Next, I update hosts file and add alfredapp.localhost to point to localhost. Edit /etc/hosts (you will need to sudo edit this) and add the following line:
127.0.0.1 alfredapp.localhost
Now visiting http://alfredapp.localhost in my browser and magically it works. You can just repeat step 6 for every site you want to add!
Wow, that’s easy! What next?
The next obvious step would be to configure your DNS so that *.localhost resolves to localhost. If you did this, then there is ZERO config to do to setup your local mirrors… simply create folders, populate them, and visit the domain in your browser! DNS configuration is a WHOLE different ballgame, which is why I’m not covering it here.
I hope that helps. Let me know if you have any comments if you have found this useful or if you know of better ways of doing this.
Cheers,
Andrew
Great post. It’s nice to know how this works under the hood.
That said, @tylerhall’s VirtualHostX app (http://clickontyler.com/virtualhostx/) is another great option for us lazy folk.
ok, nice.
but now tell us how to make an alfred.
One thing I had issues with some time ago when using .local was request speed. My local requests were super slow and they should always be faster because of no transit time.
For me anyway when I used .local OS X first search for computers on the local network because it maps machines as {MACHINE_NAME}.local. I have since changed all my local hosts to .funk and that made a huge speed difference.
Just a heads up in case anyone else has a speed issue.
I know this is a bit slow, but I’ve now updated this to .localhost, cheers! 🙂
Just wanted to suggest that on your local machine you can make this a bit easier by telling Apache to include a conf directory full of Vhost that live in your home directory. This way you don’t have to worry as much about permissions (as long as Apache can read the file) and you don’t have to dig around obscure directories to get at the conf files.
Also do you really want to pay $40 for VirtualHostX to make the 6 lines in line 4?
Hi Geoff,
I’m not sure who you are commenting to – but the whole point in this blog post is so that you don’t have to buy 3rd party software AND once setup as described, you don’t even need to touch configuration files… you can just create a folder and it’s automatically setup.
Cheers,
Andrew
Alright, I read this the day you wrote it and have been using this technique since I read it, just adding a row into hosts each time. But now I’m ready for a DNS looky up thing so I don’t have to do that step. I’ve looked all over the place, and it doesn’t seem very simple.
Any change you’re gonna make a blog post about that? or can you point me to a resource that would help me with this?
Also, I wanted to point out that on Macs (I think starting with Lion), .local looks up Bonjour stuff or whatever first, and so people are experiencing a ~10 delay before loading their pages, so you should use something other than .local.
Technically, the only “guaranteed” top level domain that will never someday be used is .localhost (or you could probably get away with .test), and it is set aside for this reason (references: in English: https://secure.wikimedia.org/wikipedia/en/wiki/.localhost, https://secure.wikimedia.org/wikipedia/en/wiki/.test; in geek: https://tools.ietf.org/html/rfc2606).
That’s a great extra bit of info (the .local delay), thanks!
As for DNS, the easiest way to do this would be to run your own BIND server which can be rather complicated to setup and easy to break…. BUT this allows for wildcarded domains so you could just assign *.tld to an internal IP address. If I get some time in the future, I’ll have a bit of a play with BIND on OS X and see if there are easy ways to setup.