Outils personnels
Vous êtes ici : Accueil Python Run Django with SCGI
Se connecter


Mot de passe oublié ?
Nouvel utilisateur ?
 

Run Django with SCGI

Par Benjamin Poulain Dernière modification 16:51

This document describe how to run Django with SCGI and how to configure Apache to use it.

Thanks to flup, Django can be run in a separate process and accessed by the web server with SCGI or FastCGI. This possibility is not well documented so this document will present how to do it with Apache.

Prerequisite

First, you need flup, a Python module providing the APIs for SCGI, FastCGI and WSGI. This module is generally named python-flup in the distribution packages.

Next, you need to install and enable mod_scgi and mod_rewrite for Apache.

To enable mod_scgi, you need to create symbolic a symbolic link for the module from apache2/mod-available to apache2/mod-enabled, and then reload apache:

cd /etc/apache2/mods-enabled/
ln -s ../mods-available/scgi.load
/etc/init.d/apache2 reload

The method for enabling it is the same as for mod_scgi.

Running Django

The script manage.py can be used to create a SCGI server, you just need to start it with runfcgi. For example:

python manage.py runfcgi protocol=scgi method=prefork host=127.0.0.1 port=40000

You can tweak the configuration with some field when you start the server:

  • protocol: scgi, fcgi or ajp
  • method: prefork or threaded. Use threaded if the resources are limited or if the server is not under high load
  • maxrequests: limit on the number of request served at the same time. Rule of thumb: number of core + 2

Configuring Apache

Finally, you need to configure Apache to connect to Django over SCGI to serve the requests.

Here is an example of my configuration:

<VirtualHost *:80>
  ServerName www.linuxcertif.com
  ServerAlias www.linuxcertif.com

  DocumentRoot /home/linuxcertif/
  Alias /media /var/lib/python-support/python2.5/django/contrib/admin/media

  SCGIMount /scgi/ 127.0.0.1:40000
  RewriteEngine On
  RewriteRule ^/(media.*)$ /$1 [QSA,L,PT]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^/(.*)$ /scgi/$1 [QSA,L,PT]
</VirtualHost>

Let's see what is important here.

First, you need to "mount" the server on a certain path. Here is the line to achieve this:

  SCGIMount /scgi/ 127.0.0.1:40000

This says: all access to /scgi/ will be served over SCGI by the server at 127.0.01:4000 (luckily it is the address we had configured for starting the Django application).

Why not mounting the server on the root ("/")? Because we want the static file to be served directly by Apache (much faster). So we use mod_rewrite to redirect the root to SCGI, while still using Apache for static files:

  RewriteEngine On
  RewriteRule ^/(media.*)$ /$1 [QSA,L,PT]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^/(.*)$ /scgi/$1 [QSA,L,PT]

And voilà!

Performance

For my configuration, the best performance are achieved with mod_python. However, this method has become a problem because of:

  1. Security: all my Django applications were running under the same user: www-data. This was also making SELinux totally useless.
  2. Resource: every instance of Apache is running with an Python interpreter with all the application. This use a lot of ram.
  3. Because of (2), the static files had to be served by another server (because it was slow to serve them with the bloated apache)
  4. Some of my Django applications have a slow startup, this was slowing down all the other applications.
  5. Some oddities of mod_django

To avoid those problems, there is SCGI, FastCGI, AJP, WSGI. With WSGI, the startup time of the interpreter was a problem so SCGI is the best second solution for my configuration.

Actions sur le document