Mapping subdomains to subdirectories with Apache - the easy way

17 10 2008

For some time now, I have been mapping projects to subdomains on my development server. In practice, this means that I access my websites thorugh project1.mydomain.com, project2.mydomain.com, etc. This way, I only need one domain name for all my projects in development, and still have the benefit of having each project reside on a separate (sub)domain, which simplifies the use of SEF URLs.

One way to map each project to it’s own subdomain is by creating one VirtualHost for each project. Although this process can be automated to some extent, it is still tiresome having to do this every time you start a new project. In addition, you quickly end up with a lot of copies of basically the same configuration file, the only difference being the subdomain name and the directory. Clearly, this is not a very DRY approach.

To achieve this mapping automatically - without the need for multiple virtual hosts - I have been using mod_rewrite in the web root directory to map subdomains to subdirectories. So, for the example above, I would have two subdirectories - project1 and project2 - each containing one of the websites I’m currently working on. The script responsible for making this work, was an .htaccess file in the web root (parent) directory, the contents of which looked something like this:

RewriteCond %{ENV:REDIRECT_SUBDOMAIN} =""
RewriteCond %{HTTP_HOST} ([a-z0-9][-a-z0-9]+)\.mydomain\.com\.?(:80)?$ [NC]
RewriteCond %{DOCUMENT_ROOT}/%1 -d
RewriteRule ^(.*) %1/$1 [E=SUBDOMAIN:%1,L]
RewriteRule ^ - [E=SUBDOMAIN:%{ENV:REDIRECT_SUBDOMAIN},L]

I found this code in a webmasterworld.com forum post, after devising something similar myself. While this solution works fine in most cases, it does have some drawbacks. The one that bothered me most is that the DOCUMENT_ROOT environment variable is set to the web root and not the project root directory. This can cause all sorts of problems for scripts relying on it.

Looking for a way to circumvent this problem, I inadvertently stumbled upon this page: Dynamically configured mass virtual hosting and was amazed at how easily this subdomain to subfolder mapping can be done with Apache. All you have to do, is replace the DocumentRoot line in the Apache config file with this:

VirtualDocumentRoot /var/www/%1/

What this does, is it takes the first part of the requested host header (everything up to the first period) and sets the DocumentRoot accordingly. So, project1.mydomain.com now points to /var/www/project1/, project2.mydomain.com to /var/www/project2/, etc. For this to work though, you will need mod_vhost_alias enabled in your Apache configuration, however that should not be a problem.

And voilà, there you have it. No more need for weird rewrite rules, while at the same time fixing the DOCUMENT_ROOT environment variable problem.

In the end, I would just like to point out that I have done quite some googling on the subject when I was first implementing this, and none of the blog/forum posts I came accross suggested a solution like this. I may have been using the wrong keywords in my searches, but I am more under the impression that people just don’t know about this feature. In any case, I hope that this post helps someone who’s looking for answers on the subject.

Tags: , ,

Related posts


Actions

Informations

8 responses to “Mapping subdomains to subdirectories with Apache - the easy way”

3 03 2009
matt (04:56:07) :

hmm very interesting would this redirect urls written as

http://www.xyz.example.com as well?

3 03 2009
Jure Merhar (11:59:19) :

Hi, Matt,

http://www.xyz.example.com would be directed to the /var/www/www directory, which is probably not the desired effect.

To make these kind of URLs work, you can modify the configuration setting like this:
VirtualDocumentRoot /var/www/%-3/
This tells Apache to use the third part from the right. With this change all of the following URLs will be directed to /var/www/xyz:
http://xyz.example.com
http://www.xyz.example.com
http://en.xyz.example.com
http://www.en.xyz.example.com

4 03 2009
matt (17:37:04) :

ahh i see that’s some pretty cool stuff, a whole lot easier than the .htaccess files I’m using now

29 09 2009
Eric (14:48:35) :

I’ve been looking for this forever! Thanks for documenting and sharing!!!

25 01 2010
Aaron (05:05:44) :

So, how do you get the Virtual Document Root to only affect subdomains.

I just tried adding it to a VirtualHost container in my Apache config file and it makes the WWW of my website fail.

25 01 2010
Jure Merhar (10:30:04) :

Hi, Aaron,

www is just a subdomain like any other. One way to work around your problem would be to add a .htaccess file in the www directory (the one where the www subdomain points) with a 301 redirect to a url without the www subdomain.

24 02 2010
Alexei Shein (12:09:20) :

This blog post was a bliss for me, the only thing it lacked for me is some reference on how to set up localhost to resolve the subdomains back itself, cause I don’t happen to have a separate domain for my win32 dev machine with a dynamic external ip. Had to resort to brute ways of editing the hosts file. Maybe there’s a better solution i’m unaware of, would be nice to see something on the matter here.
Thanks again!

24 02 2010
Jure Merhar (12:32:39) :

Hi, Alexei,

I’m glad the post was helpful to you.

As far as I know, the Windows hosts file does not support wildcards, as opposed to the Linux counterpart, which does. You could, however, install a DNS server on the dev machine.

Of course there’s always the option of switching to Linux. ;)

Leave a comment

You can use these tags : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="">