Macroify your Apache Virtual Hosts
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.
#Apache — 20 December 2020
Jan 2020 Update: I’ve since moved on to the world of MacOS, and I use Valet (as of 2017 – 18). If you develop on Windows, I’m keeping this here in case it’s of any help.
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.
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:
<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).
<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.
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, resulting in 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):
<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 Acrylic, 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).