Ben Eberle
Web Design &
Development

Setting Up Virtual Hosts on Mac OSX

Apache


Share this post

Working locally is key to faster development, and setting up PHP and MySQL to run on my local machine was the first step in establishing a solid development environment. A next, and often overlooked, step is to configure apache with virtual hosts. Virtual hosts alow you to create custom domains from which to serve your projects files locally, so this:

http://localhost/client1/project2/httpdocs/

can become this:

http://project2.dev

Here’s how to do it.

  1. Open /private/etc/hosts and add a line at the bottom of file for each host you intend to create. Each line should begin with 127.0.0.1followed by a space and then the name of the host.
    ##
    # Host Database
    #
    # localhost is used to configure the loopback interface
    # when the system is booting.  Do not change this entry.
    ##
    127.0.0.1	localhost
    255.255.255.255	broadcasthost
    ::1             localhost
    
    127.0.0.1 beneberle.local
    127.0.0.1 dev.beneberle.dev
    
    ## Freelance
    127.0.0.1 localhost.dev
    127.0.0.1 mayerbuilt.dev
    
    ## CRF
    127.0.0.1 admin.crf.dev
    127.0.0.1 tvtconference.dev
    
    
  2. Save the file, authenticating if necessary
  3. Open the main Apache configuration file, httpd.conf, located at /private/etc/apache2/httpd.conf
  4. Look for the lines that begin:
    # Virtual hosts
    #Include /private/etc/apache2/extra/httpd-vhosts.conf
  5. If the second line is commented out (hash tag to start the line, as above), remove the hash tag. This instructs apache to load the configuration file for virtual hosts, which now needs editing.
  6. Open httpd-vhosts.conf located at /private/etc/apache2/extra/httpd-vhosts.conf. It should look something like this:
    # Use name-based virtual hosting.
    #
    NameVirtualHost *:80
    
    #
    # VirtualHost example:
    # Almost any Apache directive may go into a VirtualHost container.
    # The first VirtualHost section is used for all requests that do not
    # match a ServerName or ServerAlias in any <VirtualHost> block.
    #
    <VirtualHost *:80>
    	ServerAdmin <a href="mailto:webmaster [at] dummy-host [dot] example [dot] com">webmaster [at] dummy-host [dot] example [dot] com</a>
    	DocumentRoot &quot;/usr/docs/dummy-host.example.com&quot;
    	ServerName dummy-host.example.com
    	ServerAlias www.dummy-host.example.com
    	ErrorLog &quot;/private/var/log/apache2/dummy-host.example.com-error_log&quot;
    	CustomLog &quot;/private/var/log/apache2/dummy-host.example.com-access_log&quot; common
    &lt;/VirtualHost&gt;
    
    &lt;VirtualHost *:80&gt;
    	ServerAdmin <a href="mailto:webmaster [at] dummy-host2 [dot] example [dot] com">webmaster [at] dummy-host2 [dot] example [dot] com</a>
    	DocumentRoot &quot;/usr/docs/dummy-host2.example.com&quot;
    	ServerName dummy-host2.example.com
    	ErrorLog &quot;/private/var/log/apache2/dummy-host2.example.com-error_log&quot;
    	CustomLog &quot;/private/var/log/apache2/dummy-host2.example.com-access_log&quot; common
    &lt;/VirtualHost&gt;
    

    Lines 27–42 are examples of virtual host definitions. You need to replace these with your own definitions. When you enable virtual hosting, Apache disables the main server root, so the first definition needs to reproduce it.

  7. Replace the example definitions with your own. The ServerName option you use here needs to equal the hosts domain you added earlier. You do not need to use all of the options given, the only two that are required are ServerName and DocumentRoot. This is sufficient:
    DocumentRoot "/Users/beneb/Sites/mayerbuilders.com/httpdocs"
    ServerName mayerbuilt.dev

    When complete, your new vhosts file should look something like this:

    &lt;VirtualHost *:80&gt;
       DocumentRoot &quot;/Library/WebServer/Documents&quot;
       ServerName localhost
    &lt;/VirtualHost&gt;
    
    #### Freelance Virtual Hosts ####
    
    # benberle.dev #
    &lt;VirtualHost *:80&gt;
        ServerAdmin <a href="mailto:beneberle [at] gmail [dot] com">beneberle [at] gmail [dot] com</a>
        DocumentRoot &quot;/Users/beneb/Sites/beneberle.com/httpdocs&quot;
        ServerName beneberle.dev
        ErrorLog &quot;/private/var/log/apache2/beneberle.dev-error_log&quot;
        CustomLog &quot;/private/var/log/apache2/beneberle.dev-access_log&quot; common
    &lt;/VirtualHost&gt;
    
    # localhost.dev #
    &lt;VirtualHost *:80&gt;
        ServerAdmin <a href="mailto:beneberle [at] gmail [dot] com">beneberle [at] gmail [dot] com</a>
        DocumentRoot &quot;/Users/beneb/Sites/&quot;
        ServerName localhost.dev
        ServerAlias www.localhost.dev
        ErrorLog &quot;/private/var/log/apache2/localhost.dev-error_log&quot;
        CustomLog &quot;/private/var/log/apache2/localhost.dev-access_log&quot; common
    &lt;/VirtualHost&gt;
    
  8. Restart apache by either opening up Preferences > Sharing and toggle web sharing off then on again, or, in terminal, enter:
    sudo apachectl restart
  9. Test that everything is working by entering one of your newly created virtual hosts in your browser’s address bar. In the example above, it would be mayerbuilt.dev. If you don’t see your local site, something’s wrong. You might need to clear your browser’s cache (specifically it’s DNS cache) before you can pull up your local site

That should do it, unless, like me, you browsed to your site and encountered nasty 404 errors when trying to navigate around. I had a hunch my .htaccess file was being ignored, and sure enough, after some basic tests, I discovered that while mod_rewrite was working for files served from the default /Library/WebServer/Documents folder, it was not for the newly created virtual hosts.

To fix the problem, I opened up /private/etc/apache2/extra/httpd-vhosts.conf again and added the following directives:

<Directory "/Users/beneb/Sites">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

When using the snippet above, change “beneb” to your home directory. The main thing here is AllowOverride. AllowOverride controls what directives may be placed in .htaccess files. Set this to “All”. This tells apache that it’s OK to allow rewriting URLs from files in the /Users/beneb/Sites directory.

Read more