At work we yestoday decided to update our internal url structure for our client test sites, issue management systems and such arround a bit. Seeing as we decided on purchasing a genuine signed ssl wildcard certificate, we needed to change our url’s a bit.
We used to have a url schema consisting of the following components:
That made for very long url’s, and furthermore, the url’s would not be supported by a
*.companyname.tld. Based on this infomation, and wanting to create a more generelized, nicer url schema, we choose to cross over to the following schema:
Which besides from supporting a wildcard ssl certificate just fine, just, well, looks nicer.
Either way, me beeing in charge of the contents in
/etc/, and getting a little sick of growing apache configuration files, I chooose to write some macros to configure our project sites.
We generally have 2 types of project sites. django based sites, and PHP based sites.
A typical django apache configuration consists of a VirtualHost and some mod_python settings inside a Location block. Lot’s of configuration, very little actual diffrence between the configration projects in between.
An example of a django based application running inside a apache VirtualHost, could look like this:
<VirtualHost *:80> ServerName test-project.company.tld <Location /> SetHandler python-program PythonHandler django.core.handlers.modpython PythonPath "['/path/to/project', '/other/path/to/inject']" SetEnv DJANGO_SETTINGS_MODULE project.settings </Location> <Location /media/> SetHandler none </Location> Alias /media/admin/ /path/to/django/contrib/admin/media/ Alias /media/ /path/to/project/media/ </VirtualHost>
And the on top of that comes SSL configuration, auth and such. 25 lines of configuration per django site. Now, I really wanted to acomplish two things.
- Make the configuration easier to maintain
- Enable other users to setup sites without knowing the depths of django and
Now, apache configuration, meet mod_macro. The solution to my problem was very simple. Create a macro that handles all the django configuration, given 4 parameters. A server name (i.e. the url), the parent directory of the django site and the module name of the site.
So i started building my macro.
<Macro DjangoSite $servername $root $module> <VirtualHost *:80> ServerName $servername <Location /> SetHandler python-program PythonHandler django.core.handlers.modpython PythonPath "['/common/path/to/inject', '$root']" SetEnv DJANGO_SETTINGS_MODULE $modulename.settings </Location> <Location /media/> SetHandler none </Location> Alias /media/admin/ /path/to/django/contrib/admin/media/ Alias /media/ $root/$module/media/ </VirtualHost> </Macro>
mod_macro is really simple, it will do a longest-match search and replace on the macro’s content. So, if we had a django site in
/path/to/djangosite/testsite/ the above macro could be used as:
Use DjangoSite www.example.org /path/to/djangosite/ testsite
Which would expand to:
<VirtualHost *:80> ServerName www.example.org <Location /> SetHandler python-program PythonHandler django.core.handlers.modpython PythonPath "['/common/path/to/inject', '/path/to/djangosite/']" SetEnv DJANGO_SETTINGS_MODULE testsite.settings </Location> <Location /media/> SetHandler none </Location> Alias /media/admin/ /path/to/django/contrib/admin/media/ Alias /media/ /path/to/djangosite/testsite/media/ </VirtualHost>
Hope you find this infomation a little useful. I actually like looking at our apache configuration file now.