In the process of setting up a new web-server with Mosso’s CloudServer, I came up across an interesting problem that took be the better part of the day to figure out.

The new server is completely unmanaged, which means that I have no web control panel to manage things. But worry not, that’s actually a good thing, because it means I have no web control panel to complicate and fuck up things either.

But it meant I had to setup Apache manually, including the vhosts so that my domain get mapped to the correct content. The problem is I have north of ten domains, each with their own subdomains. I could do it the standard and documented way of adding a VirtualHost for each domain, or I can be clever and have it do the work for me.

My first idea was to go with mod_vhost_alias:

UseCanonicalName Off

LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon

VirtualDocumentRoot /home/kenneth/www/%0/public
VirtualScriptAlias /home/kenneth/www/%0/cgi-bin

This worked like magic, automatically translating the domain requested to the path.* would translate to /home/kenneth/www/*. But, would translate to a folder named This meant one of two things: either I had to create dirty symlinks in my www folder, or anybody accessing my domain from the www. subdomain would get a 404 error, both of which are unacceptable.

Another option would be to change that code like such:

VirtualDocumentRoot /home/kenneth/www/%-2.0.%-1.0/public
VirtualScriptAlias /home/kenneth/www/%-2.0.%-1.0/cgi-bin

This works by taking the last two parts of a domain, but it has two big flaws. Firstly, it completely ignores any subdomains. Secondly, it doesn’t work with multiple-tld domains, such as domains.

After a whole afternoon of trying different things, I came to the optimal solution, through URL rewriting.

With this solution, domains, whether they have www. or not, map to the same domain.tld folder, and subdomains also map to folders in the same root folder (www, in my case).

UseCanonicalName Off

<Directory /home>
Options FollowSymLinks ExecCGIAllowOverride All

RewriteEngine On

RewriteCond %{REQUEST_URI} !/home/kenneth/www
RewriteCond %{REQUEST_URI} !^/icons/
RewriteCond %{REQUEST_URI} !^/cgi-bin/
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.*)$ [NC]
RewriteRule ^/(.*)$ /home/kenneth/www/%1/public/$1

RewriteCond %{REQUEST_URI} !/home/kenneth/www
RewriteCond %{REQUEST_URI} ^/cgi-bin/
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.*)$ [NC]
RewriteRule ^/(.*)$ /home/kenneth/www/%1/cgi-bin/$1 [T=application/x-httpd-cgi]

This entry was posted on Wednesday, April 29th, 2009 at 5:57 pm and is filed under English, Internet, Programming. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
Add your thoughts!
April 30th, 2009 at 12:35 am

How do you separate your logs out, or do you just have one big communal access and error log?

Slavi mouthes
August 14th, 2010 at 10:53 pm

the log can be parsed separately with Perl or other existing tools

Have something to say?