Cloud Zone is brought to you in partnership with:

Rob Allen has been programming with PHP since 1999 and is a member of the PHP community. He is the lead author of Zend Framework in Action and is a contributor to Zend Framework, developing the Zend_Config component. Rob holds a Masters degree in Electronic Engineering from the University of Birmingham in the UK and is the Technical Director of Big Room Internet in the UK, focussing on project management and the company’s future technologies. Rob is a DZone MVB and is not an employee of DZone and has posted 37 posts at DZone. You can read more from them at their website. View Full User Profile

Drop a Folder into a Directory and have it Automatically Turned into an Apache vhost

03.26.2012
| 9263 views |
  • submit to reddit

One thing that I've wanted to implement for a while now is automatic vhosts on my dev box. The idea is that I want to drop a folder into a directory and have it automatically turned into a vhost for me accessible at http://foldername.dev. It turns out that this isn't nearly as hard as expected which is usually the case with things that I've been putting off!

This is how to do it.

Apache configuration

The Apache magic is in an extension called mod_vhost_alias which you may need to enable in your httpd.conf file.

You can then set up the VirtualHost wherever you keep such things. On a stock OS X, the extras/httpd-vhosts.conf file is used.

Add the following to the bottom:

<VirtualHost *:80>
    VirtualDocumentRoot "/www/dev/%1/public"
    ServerName vhosts.dev
    ServerAlias *.dev
    UseCanonicalName Off
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    ErrorLog "/www/dev/vhosts-error_log"
    <Directory "/www/dev/*">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

In the VirtualHost configuration, I have used the ServerAlias and VirtualDocumentRoot directives to map http://foldername.dev to the directory /www/dev/foldername/public. Hence, any folder that I place in /www/dev will have its own virtual host. Alter these appropriately for your set-up.

Don't forget to restart Apache.

Unfortunately, the computer hasn't a clue how to handle http://foldername.dev and the obvious solution is to run a local DNS server. Another solution is to use a PAC file.

DNS server configuration

This is easy enough with dnsmasq. On OS X, use Homebrew to install like this: brew install dnsmasq. On Linux, use your package manager; on Windows, you're own your own!

Note that on OS X, you should set it to start up automatically using launchd as noted in the instructions after installation. You also need to copy the configuration file to /etc using: cp /usr/local/Cellar/dnsmasq/2.57/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf (or whatever the latest version number is). on Linux, I would guess that your package manager provides a dnsmasq.conf file in /etc or /etc/dnsmasq.

Next, edit dnsmasq.conf file and added the following lines to the bottom:

listen-address=127.0.0.1
address=/.dev/127.0.0.1

Add the name server to your network configuration

On OS X, Go to System Preferences -> Network -> {Wifi or Ethernet} -> Advanced… -> DNS and click on + button at the bottom of the left hand panel and add 127.0.0.1 to the list of DNS servers. Drag 127.0.0.1 at the top of the list.

On Linux, you need to edit /etc/resolv.conf and add nameserver 127.0.0.1 to the file. Alternatively, you can use the appropriate GUI tools...

Restart dnsmasq and you should now be able to execute host test.dev on the command line and see 127.0.0.1 as the resultant address.

Alternative to DNS server: PAC file

Since publishing this article, Chris Morell pointed out that you can also use PAC files rather than install a DNS server. Details are on his blog post.

Check it works

Create a directory called test in your dev directory. Within test, create public/index.php and within index.php add some code to prove it works. e.g. <?php echo "Hello World"; ?>

If you navigate to http://test.dev, you should see "Hello World" displayed.

Caveats

A couple of caveats:

  • DOCUMENT_ROOT is not /www/dev/test as you'd expect. Instead it is the global document root.
  • If you use mod_rewrite, then you'll need a RewriteBase / in your .htaccess file. Alternatively, you can change the <Directory> section of your vhost to do the rewriting for you if all your projects are alike. Something like this should work:

        <Directory "/www/dev/*">
            Options Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            Allow from all
    
            RewriteEngine On
            RewriteBase /
            RewriteCond %{REQUEST_FILENAME} -s [OR]
            RewriteCond %{REQUEST_FILENAME} -l [OR]
            RewriteCond %{REQUEST_FILENAME} -d
            RewriteRule ^.*$ - [NC,L]
            RewriteRule ^.*$ index.php [NC,L]
        </Directory>
    

All done

That's it. You can now create as many projects as you like without having to worry about setting up new virtual hosts or modifying your host's file!

Published at DZone with permission of Rob Allen, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)