Tuesday, December 7, 2010

Dynamic Apache configuration for Development Servers

When configuring a development environment for PHP, the usual configuration is a LAMP server with mod_userdir enabled to assign each user their own URL (/~username).  I always though this URL format was not elegant.
I think the better way is to have the username in the domain part of the URL:
Configuring the server to handle this type of URL requires having per-user configuration files/sections.  It also requires restarting Apache every time this files are changed.  The solution was to use mod_vhost_alias which allows mapping domains to directories (More information found at Dynamically Configured Mass Virtual Hosting).

1. Solution (mod_vhost_alias)

The mod_vhost_alias module allows us to map parts of the domain name to directories.  The syntax used is similar to printf().  The following tables from the Apache website describes how the mapping is done:
%%insert a %
%pinsert the port number of the virtual host
%N.Minsert (part of) the name
0the whole name
1the first part
2the second part
-1the last part
-2the penultimate part
2+the second and all subsequent parts
-2+the penultimate and all preceding parts
1+ and -1+the same as 0
* For more information about this table visit http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html#interpol

1.1. DNS
To make this work we need  a wildcard A record pointing to the development server:
*.dev.example.com =>  #sample IP address (use your server's IP address in place or
1.2. Apache
In the default virtual host (or vhost of your choice) the following configuration is necessary:

ServerName dev.example.com
ServerAlias *.dev.example.com 
VirtualDocumentRoot /home/%-4.0/public_html

%-4.0   = username in [username].dev.example.com

The important directive to pay attention to is "VirtualDocumentRoot /home/%-4.0/public_html".  I tells apache to dynamically assign the document root based on the domain.

2. Going Even Further (sub domain per application)

With a wildcard a record and mod_vhost_alias we can assign a domain to each user app.   The format I use is the following:
to achieve this we add %-5+ to the VirtualDocumentRoot directive:
VirtualDocumentRoot /home/%-4.0/public_html/%-5+
%-4.0   = username in my-app.[username].dev.example.com
%-5+ = app in [app].username.dev.example.com

This configuration maps http://myapp.username.dev.example.com to /home/username/public_html/myapp

2.1. Omitting parts of the sub-domain 
A side effect of using this technique is that if any of the sub-domain parts is missing, apache will replace it with an underscore ( _ ):
http://username.dev.example.com  maps to /home/username/public_html/_/
http://dev.example.com  maps to /home/_/public_html/_/

This is not necessarily a bad side effect.  We can actually create pages inside underscore directories to display customized messages.


No comments:

Post a Comment