How to run multiple websites from one Django project
It is sometimes beneficial to run two or more web sites or subdomains of a site from a single Django code base. Each Django app in the project can then power a website on a different domain, but all the apps can still share a single database with a single administrative interface.
In order to achieve this, one needs to prepare separate WSGI sockets for each website. You can provide a separate settings.py
file for each website, thus selecting which apps will be active on that site and which urls.py
file will be the ROOT_URLCONF
and handle the routing of requests for that domain.
In this example I will show how to set up two subdomains of one site running on the WebFaction hosting service.
Preliminaries
First of all, we need to set up:
1) a single WebFaction application running Django,
2) a WebFaction domain with two subdomains (separate domains could also be used),
3) a WebFaction website running on both domains and powered by the Django application.
Apache configuration
Secondly, we need to edit the http.conf
file, which is stored in the ~/webapps/APPLICATION_NAME/apache2/conf
directory.
In this file, we need to create a <VirtualHost>
directive for each subdomain we are using...
# Virtual hosts setup
NameVirtualHost *
<VirtualHost *>
ServerName subdomain1.example.com
WSGIDaemonProcess APPLICATION_NAME processes=5 python-path=/home/USERNAME/webapps/APPLICATION_NAME:/home/USERNAME/webapps/APPLICATION_NAME/lib/python2.6 threads=1
WSGIScriptAlias / /home/USERNAME/webapps/APPLICATION_NAME/subdomain1.wsgi
</VirtualHost>
<VirtualHost *>
ServerName subdomain2.example.com
WSGIDaemonProcess APPLICATION_NAME_www processes=5 python-path=/home/USERNAME/webapps/APPLICATION_NAME:/home/USERNAME/webapps/APPLICATION_NAME/lib/python2.6 threads=1
WSGIScriptAlias / /home/USERNAME/webapps/APPLICATION_NAME/subdomain2.wsgi
</VirtualHost>
The WSGIDaemonProcess
directive specifies the configuration of the server deamon processes which will power each domain. In the example above, each domain is powered by 5 separate processes. This consumes 5 times more memory then a single process, but allows you to handle more requests simultaneously. This directive also allows you to specify the PYTHONPATH
specific to your Django codebase and library directory.
The WSGIScriptAlias
allows you to specify, which file will start the WSGI
socket for the domain.
WSGI startup files
Next we need to create the two .wsgi files:
/home/USERNAME/webapps/APPLICATION_NAME/subdomain1.wsgi
/home/USERNAME/webapps/APPLICATION_NAME/subdomain2.wsgi
Each file should contain the following code with appropriately subdomain1
or subdomain2
, and PROJECT_NAME
should be changed to the name of the directory which holds your Django project files.
import os
import sys
from django.core.handlers.wsgi import WSGIHandler
os.environ['DJANGO_SETTINGS_MODULE'] = 'PROJECT_NAME.subdomain1_settings' # or PROJECT_NAME.subdomain2_settings
application = WSGIHandler()
settings.py
files
Next, we need to set up the two settings.py
files. I would actually recommend setting up 3 of these, one to hold information, which is common to all domains, let's leave it named settings.py
and the two domain-specific files: subdomain1_settings.py
and subdomain2_settings.py
.
The subdomain specific settings files will inherit all the defaults from the common settings.py
file, and override only those values which are specific to the domain. For instance, lets create a subdomain specific settings file, which runs a different then default set of apps and uses a different urls.py
as ROOT_URLCONF
. Such a file should contain the following code:
from settings import *
SITE_ID = 1
ROOT_URLCONF = 'subdomain1_urls'
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
# other apps specific to this domain
)
urls.py
files
Now, we just need to make the two url configuration files, which will handle the routing of requests coming into our domains. These are standard url.py
, they just have to be named, as specified in the settings.py
files, so subdomain1_urls.py
and subdomain2_urls.py
.
Conclusion
So there you have it. This technique works well on WebFaction, and I'm sure can be replicated on other hosting services, which allow you to modify Apache configuration files.
One thing to keep in mind is that running two separate WSGI
processes will use twice as much memory as running one. You can tweak the memory usage to your needs by specifying how many processes each WSGI
socket is handled by.