Apache Environment Variables and mod_wsgi

November 12, 2010

I need to be able to pass Apache Environment Variables, set on a per VirtualHost basis, through to a Django application. These need to be variables set in Apache via SetEnv, rather than operating system environment variables, as they will change for each VirtualHost.

VirtualHost config

In the Apache virtual host config, add a SetEnv directive for the values you want to set.

<VirtualHost *:80>
    ServerAdmin me@host.co.uk
    ServerName hostname

    WSGIDaemonProcess appname user=appuser group=appgroup processes=2 threads=2 stack-size=524288
    WSGIProcessGroup appname

    CustomLog /path/to/logs.log vhost_combined

    SetEnv APP_DATABASE_NAME app_db

    WSGIScriptAlias / /path/to/app.wsgi

     Alias /site_media/ "/path/to/site_media/"
     Alias /media/ "/path/to/django/contrib/admin/media/"

     <Directory /path/to/site_media/>
       Order allow,deny
       Allow from all
       Options -Indexes
     </Directory>
</VirtualHost>

Note the SetEnv APP_DATABASE_NAME app_db. This sets the APP_DATABASE_NAME variable that we'll pick up in a minute. You don't need quotes around the value.

WSGI File

In the WSGI file (in this example /path/to/app.wsgi) we need to copy the required environment variables into the os.environ, so that we can then see them from settings.py.

The path magic at the start of this file assumes that the wsgi file is in the same directory as settings.py, one level below the dir that needs adding to sys.path.

import os, sys
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_DIR = os.path.abspath(os.path.join(BASE_DIR, '..'))

sys.path.append(PROJECT_DIR)
os.environ['DJANGO_SETTINGS_MODULE'] = 'app.settings'

import django.core.handlers.wsgi
_application = django.core.handlers.wsgi.WSGIHandler()

def application(environ, start_response):
  os.environ['MY_DATABASE_NAME'] = environ['APP_DATABASE_NAME']
  return _application(environ, start_response)

import app.monitor
app.monitor.start(interval=1.0)

settings.py

We can now reference MY_DATABASE_NAME from settings.py

import os
DATABASE_NAME = os.environ['MY_DATABASE_NAME']