Apache VirtualHost – Using VirtualDocumentRoot Only if Suitable Document Root Exists

apache-2.2virtualhost

I'd like to set up an environment where Apache virtual hosts can be dynamically created without reloading the configuration.

I can do this with mod_vhost_alias, I set up my default virtual host something like this

<VirtualHost *>
  UseCanonicalName Off
  VirtualDocumentRoot /var/www/sandboxes/domains/%0
  ServerName catchall.host
</VirtualHost>

That works just fine, but if a request is made for a hostname which isn't currently set up, I get a 404 Not Found error.

What I'd really like to do is only have this VirtualHost kick in only if the document root exists, otherwise have it try to match another vhost (in other words, make the presence of the the VirtualDocumentRoot work in the same way as using a ServerAlias)

I tried making this the second vhost, with the first vhost just handling all requests, but this didn't work – requests for domains where a VirtualDocumentRoot was configured were falling through to the default vhost.

So, how can I have dynamically configured vhosts, but with a fallback to another vhost for any which aren't configured yet?

Best Answer

I found a workaround which works for me.

I can use an ErrorDocument to pick up the 404 Error in a PHP script. At first, that seemed problematic. If there's no DocumentRoot, where will the script live?

I could use a URL for the error message, served from a different domain. However, in testing I found no way of knowing what the originally requested domain was.

The answer was to Alias a directory and serve the errors out of that, so my vhost looks like this

<VirtualHost *>
  UseCanonicalName Off
  VirtualDocumentRoot /var/www/sandboxes/domains/%0
  ServerName catchall.host
  Alias /errors /var/www/default/errors/
  ErrorDocument 404 /errors/notfound.php
</VirtualHost>

Now, when an unconfigured domain is requested, the script at /var/www/default/errors/notfound.php is invoked instead. This script can check $_SERVER['HTTP_HOST'] to see what domain was requested. If it is actually configured, then we have a regular 404. If it's not configured, we can display some alternate error message. In my case, it's where I show a UI to help set the vhost up.

Related Topic