Tutorial for: uWSGI
In the previous tutorial, I explained how to prepare a server with uWSGI and Nginx to work with Massive Python application hosting. This tutorial continues this and explains how to configure this solution to work with various versions of Django.
The first thing we need to do after configuring Nginx and uWSGI is to create a base INI file for each domain we which to host. Go into the /srv/sites directory we created in the last tutorial and create a file called django12_base. This will be used when you need to host a legacy Django app, which is not yet compatible with Django 1.3+. In this file, enter the following data:
[uwsgi] djangoproject = /srv/apps/%n/ env = DJANGO_SETTINGS_MODULE=%n.settings pymodule-alias = %n=%(djangoproject) chdir = %(djangoproject) virtualenv = /opt/django12-env module = django.core.handlers.wsgi:WSGIHandler() socket = 127.0.0.1:0 master = true processes = 5 threads = 100 idle = 3600 uid = someuser gid = someuser subscribe-to = 127.0.0.1:3032:@%(djangoproject)/domains.txt
This base file explains how to serve a Django 1.2 application, and where to locate it's virtualenv, which we will create in a few moments. It also references a domains.txt file, which you will use to configure which domain names a app will be hosted on. You should update the processes and threads above to support your environments needs. Depending on how you choose to run uWSGI, the uid and gid here should reflect the correct user of the application, or the one which runs uWSGI.
Once this file is done, go ahead and create the virtualenv. This is the recommended method of doing so:
# mkdir /opt/django12-env $ virtualenv /opt/django12-env $ source /opt/django12-env/bin/activate (django12-env)$ pip install django==1.2.7
Notice that root first creates the directory, then the regular user goes ahead and sets up the virtualenv.
Once the virtualenv is created and Django is installed, lets proceed and create a simple Django app to test the configuration:
(django12-env)$ cd /srv/apps (django12-env)$ django-admin.py startproject hello1 (django12-env)$ echo "hello1.local" > hello1/domains.txt (django12-env)$ cd ../sites (django12-env)$ ln -s django12_base hello1.ini
Now if you create an entry for hello1.local in your hosts file, and visit it in your browser. You should see the Django main welcome page for new project. If you ever make any changes to this project, just run touch on the hello1.ini file symlinked above. This is all there is to it for Django 1.2 and Django 1.3, just make a new virtualenv for 1.3 and install Django there, then create a new base file to reflect that. Then for any Django 1.3 specific projects, just symlink that base file and your all good to go. However, with a recent change to Django in 1.4, the project layout is different, so a different INI file is required:
[uwsgi] djangoproject = /srv/apps/%n pymodule-alias = %n=%(djangoproject)/%n chdir = %(djangoproject) virtualenv = /opt/django14-env module = %n.wsgi socket = 127.0.0.1:0 master = true processes = 5 threads = 100 idle = 3600 uid = someuser gid = someuser subscribe-to = 127.0.0.1:3032:@%(djangoproject)/domains.txt
The changes to note are the removal of the DJANGO_SETTINGS_MODULE environment variable, the change to the pymodule-alias option, and last but not least, the update to the module option. This will allow you to host Django 1.4 apps using this method.
In order to take full advantage of the Nginx configurations created in the previous tutorial, you should alter your Django settings.py file to have something like this:
MEDIA_ROOT = '/srv/media/hello1.local' MEDIA_URL = '/m/' STATIC_ROOT = '/srv/static/hello1.local/' STATIC_URL = '/s/'
In order to be-able to serve files to both www. and non-www. hostnames, you will need to create a symlink in the /srv/(media|static) folders, or set the PREPEND_WWW option in your Djago settings file.