Posted in Web Development 28 Dec 2016 @ 07:40 PM~4 min read

Use Macros to define your Virtual Hosts in Apache

If you’re on Windows, chances are you don’t have a handy package like Valet to make your development-workflow easier. If you’re using a standard Apache installation, this might go a long way in speeding things up.

Ever since I started developing for the web and discovered Apache, it was tedious for me to have to create a new virtual host every time I wanted to work on a new site – as if editing the hosts file was bad enough.

At the onset, I searched for a way to make a wildcard virtual host that would shorten the process of starting up a new development domain considerably. Since then, I’ve been through several iterations of this, and would like to share my current setup with you.

Config file

For starters, I’m not using the default httpd-vhosts.conf file – for some reason, I wanted my virtual hosts to be called virtuals’, and so I created a new config file for that, and included it in httpd.conf:

Include conf/virtuals.conf

Before I begin with the code, here’s the virtual host tree I’m working with now:

/var/www/
  - domain
    - public_html (document root, maps to domain.local)
    - subdomain
      - public_html (subdomain document root, maps to subdomain.domain.local)

domain and subdomain are site-roots’, which are handy for apps that need to access one level above the document root. (My favourite CMS, ProcessWire, does not do this, and I really wish it did. That way, the .htaccess override would perhaps not e so bloated. </Rant>)

To begin, we need to define two macros in the virtuals.conf file.

Directory macro

The first macro defines the structure of our directory configuration:

# Directory Macro - Default Directory configuration on a per-vhost basis

<Macro Directory $dir>
    <Directory "z:/var/www/$dir/public_html">
        Require all granted
        Options Includes Indexes FollowSymLinks
        AllowOverride All
    </Directory>
</Macro>

This is the simplest directory config you’d need, and covers most situations – it’s obviously easy enough to override. Note how $dir is pulled into the path from the macro parameter (just after the name definition).

Subdomain macro

Now, the next macro is for subdomains. Unfortunately, this is required as the wildcard approach doesn’t seem to work for me, keeping in mind that I prefer subdomain document roots to be located in the main domain’s directory (one up from its document root).

# LocalSub Macro - For specific *.*.local subs that require their own root

<Macro LocalSub $sub $domain>
    <VirtualHost 127.0.0.1>
        ServerName $sub.$domain.local
        DocumentRoot "z:/var/www/$domain/$sub/public_html"
        Use Directory $domain/$sub
    </VirtualHost>
</Macro>

This macro is called LocalSub, and pulls in two variables; one for the main domain, and the other for the subdomain. This is provided to ServerName and DocumentRoot. And lastly, this virtual uses the Directory macro we defined above.

Much like the Use directive above, we’ll need this for declaring subdomains on an individual basis as well. Unfortunately, this means an Apache-restart is required. However, this isn’t an issue for me as the process is really simple, and I don’t use many subdomains. If someone does know a better way to handle this, you’re welcome to comment below.

To create a virtual for a subdomain, simply call the Use directive:

Use LocalSub blog rockettpw

Here, blog is the subdomain, and rockettpw is the main domain. (This is my current setup, and points to blog.rockettpw.local.)

The main virtual host

Now that’s out of the way, we can proceed to create the main virtual host, which captures *.local (this should go underneath your subdomain imports):

# Main virtual host

<VirtualHost 127.0.0.1>
    UseCanonicalName Off
    ServerAlias *.local
    VirtualDocumentRoot "z:/var/www/%-2/public_html"
    Use Directory *
</VirtualHost>

If you’re not sure what %-2 is, it’s simply telling Apache to pull the * from the server alias (we need to use an alias and not a name due to the wildcard – also note that we do not need UseCanonicalName for the same reason). Specifically, it means the second last portion of the alias, where each portion is separated by a period (.).

Lastly, we import the directory config, using the macro once again. This time, however, we declare a wildcard for the directory, which would result in z:/var/www/*/public_html. This does not apply the configuration to all th directories – it is specific to the virtual being requested.

Conclusion

As you can see, the process is quite straight-forward. Once you’ve set this up, all you need to do is add a directory and document root for a new site, and don’t forget to add the entry to the hosts file.

You could, as an alternative, use Acryilic, which allows you to use wild-card hosts, like 127.0.0.1 *.local. I’m unable to get it working on my end, but it’s more than likely due to my network adapter configuration (unable to diagnose).

Loading Comments...