Sunday, March 17, 2013

Apache mod_vhost_alias VirtualDocumentRoot per second level domain name

I wanted to have a virtual document root for each second level domain name (example.com, f85.net, abc.net, etc...), with subdomain virtual document roots located underneath the main domain name.

For example:

         f85.net --> /var/www/f85.net/f85.net
     www.f85.net --> /var/www/f85.net/www.f85.net 
www.news.f85.net --> /var/www/f85.net/www.news.f85.net 
 www.example.com --> /var/www/example.com/www.example.com 
 abc.sub.pri.com --> /var/www/pri.com/abc.sub.pri.com

And so on, so that each primary domain (that gets registered with a registrar) has its own folder in /var/www.

The problem was, everything that I was trying was failing to give the desired results, because I didn't fully understand how the 'Directory Name Interpolation' was working (how Apache turns the configured VirtualDocumentRoot string into a string that represents a discrete folder each time a file is accessed.

What ended up working was:

VirtualDocumentRoot /var/www/%-2.0.%-1/%0
VirtualScriptAlias  /var/www/%-2.0.%-1/%0/cgi-bin/

I'll break this down in pieces to explain how it's working:

/var/www/%-2.0.%-1/%0
This highlighted piece is the folder that holds all of the domains.  It never changes.


/var/www/%-2.0.%-1/%0
This highlighted piece references the second value from the right of the fully qualified domain name (FQDN).  For example, in the URL "http://www.f85.net", this will give us "f85".  When you use the - symbol, Apache starts counting from the right (so "%-1" would yield "net", and "%-3" would yield "www").  The ".0" following "%-2" is also important.  Although it doesn't technically do anything ("%-2" == "%-2.0"), it allows us to add the next item without errors.


/var/www/%-2.0.%-1/%0

This highlighted piece is a dot, plain and simple (up to and including this highlighted piece, we would have "/var/www/f85.").  The reason I wanted to dedicate a paragraph to it is because it gave me the most trouble.  The first thing I tried was combining "%-2" with a period ("%-2.") Logically this would give us "f85.", right? Nope!  When Apache sees this period following a "%-2" (or any other "%x"), it expects another number after the dot, as described in the Directory Name Interpolation section of mod_vhost_alias.  This second number is used to select a single character out of the first number's text (for the "www.f85.net" example, "%-2.1" would represent the character "f".  We can use the number 0 here ("%-2.0") to tell Apache to select the entire value and not some specific character, which allows Apache to finish parsing this "%x" phrase so that we can add our "." and have it actually represent a period without breaking anything!



/var/www/%-2.0.%-1/%0
This highlighted piece is the first value from the right of the FQDN ("net", in our "www.f85.net" example).  Pretty straightforward.  Up to and including this piece, we now have "/var/www/f85.net".  So far so good, just one last piece.

/var/www/%-2.0.%-1/%0
This highlighted piece represents the entire FQDN (with a forward slash in front of it).  Up to and including this piece, we're done!  We have "/var/www/f85.net/www.f85.net".

Now, this is definitely not the first way I tried to do this, but it's the only way that I've found to work consistently across sub-domains of various depths.  Please let me know in the comments if you see a problem with this method or have a better idea!!