Need some help on your next project? Drop me an email: matt@mcollins.co.uk
Matt CollinsWeb Developer

Single Django codebase with multiple sites

All Notes

Posted on: 13/11/2015

I’ve just launched Burgopak.com, a new product showcase for Burgopak. One of the main challenges was using the existing Django-based site that runs Burgopakstudio.com, Burgopak’s consultancy business, to also run Burgopak.com. The Burgopak team wanted a single CMS that could control both sites and were keen to keep the current CMS as they were comfortable using it.

The solution came from a combination of infrastructure configuration and application configuration. Here’s how I achieved it.

Create a unique settings file for each of your sites within the codebase

Screenshot of settings file structure Screenshot of settings file structure

I started structuring the codebase to separate the Burgopak.com (dotcom) and the Burgopak Studio (studio) sites. All my Django apps sat within a corresponding directory for the site they were used on. Within my settings directory I followed the same convention, creating a set of settings files for each site that extend a common base settings file. The main advantage from doing this was that I could then specify what URLs each of the sites would use with the ROOT_URLCONF setting. I also updated TEMPLATE_DIRS so I could separate out template files for each of the sites.

More on: ROOT_URLCONF, TEMPLATE_DIRS.

Configure supervisor to run two instances of the application from the codebase

The current Burgopak Studio site was using a combination of Gunicorn and Supervisor to run the Django application behind NGINX. When using Supervisor you create configurations for ‘programs’ which supervisor will then run & monitor, restarting on crashes. By creating a program for each of the sites that specified the different settings file to use and a unique port to bind meant the codebase could be running in two modes side-by-side.

More on: Gunicorn, Supervisor

Use NGINX to route the incoming requests to the correct port

The final piece in the puzzle is to set up two virtual hosts within NGINX that route requests on the different domains to the correct port.

More on: NGINX Virtual hosts (Digital Ocean Guide)

Run your tests on one site at a time

Because of the different ROOT_URLCONF settings, running tests with the wrong settings file can lead to lots of failures when the test client can’t request URLs. I just ran two separate test runs on my Codeship builds that specified the settings file but also the path to that site's code like so:

./manage.py test --settings=burgopak.settings.dotcom.test dotcom
./manage.py test --settings=burgopak.settings.studio.test studio

More on: Codeship

Use Grappelli’s dashboard

I'm using the Grappelli theme for my Django Admin, which includes a dashboard feature. Grappelli’s dashboard feature allowed me to create two App lists, one for the models for each site so it was easy to find what you wanted in the Django Admin.

More on: Grappelli dashboard