Hosting Django under Nginx with SCGI and WSGI

Description of mod_wsgi and mod_scgi currently developed for Nginx server.

A module called mod_wsgi is currently developed for Nginx (0.5 series supported currently). Latest news we will find on Nginx wiki. To install this module you have to
  • Get the latest code (mercurial RCS):
    hg clone
  • Compile nginx adding --add-module=/ścieżka/do/mod_wsgi/ to configure, for example:
    ./configure --add-module=/ścieżka/do/mod_wsgi/
  • After compile and install you are ready to go.
Here is a part of nginx.conf for hosting Django (Django-SVN) project using mod_wsgi:
server { 
	listen       8000;
	server_name  localhost;
	wsgi_var  REQUEST_METHOD      $request_method;
	#wsgi_var  SCRIPT_NAME         $uri; # TODO
	#wsgi_var  PATH_INFO           $uri; # TODO
	wsgi_var  QUERY_STRING        $query_string;
	wsgi_var  CONTENT_TYPE        $content_type;
	wsgi_var  CONTENT_LENGTH      $content_length;
	wsgi_var  SERVER_NAME         $server_name;
	wsgi_var  SERVER_PORT         $server_port;
	wsgi_var  SERVER_PROTOCOL     $server_protocol;
	# additional variables
	# (they will be present in the WSGI environment only if not empty)
	wsgi_var  REQUEST_URI         $request_uri;
	wsgi_var  DOCUMENT_URI        $document_uri;
	wsgi_var  DOCUMENT_ROOT       $document_root;
	wsgi_var  SERVER_SOFTWARE     $nginx_version;
	wsgi_var  REMOTE_ADDR         $remote_addr;
	wsgi_var  REMOTE_PORT         $remote_port;
	wsgi_var  SERVER_ADDR         $server_addr;
	wsgi_var REMOTE_USER $remote_user;
	#wsgi_middleware  wsgiref.validate  validator;
	#wsgi_middleware  paste.lint;

	location  / {
		#client_body_buffer_size 50;
		wsgi_pass /path/to/;

		wsgi_pass_authorization off;
		wsgi_script_reloading on;
		wsgi_use_main_interpreter on;
We have to set a path to file, which is located in the project folder (for example) and has the code:
import os, sys

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
If paths are correct is should work (localhost:8000 in this example)


mod_scgi is a second module from the same developer, also in development. It does not handle full SCGI specs, so using it to host Django is currently a bit limited. Installation is very similar to the mod_wsgi install. Config looks like this:
location  / {
	## scgi_var  CONTENT_LENGTH     $content_length;
	scgi_var  QUERY_STRING       $query_string;
	scgi_var  REQUEST_METHOD     $request_method;
	scgi_var  CONTENT_TYPE       $content_type;
	## scgi_var  SCRIPT_NAME        $fastcgi_script_name;
	scgi_var  REQUEST_URI        $request_uri;
	scgi_var  DOCUMENT_URI       $document_uri;
	scgi_var  DOCUMENT_ROOT      $document_root;
	scgi_var  SERVER_PROTOCOL    $server_protocol;
	scgi_var  SCGI               1;
	scgi_var  SERVER_SOFTWARE    nginx/$nginx_version;
	scgi_var  REMOTE_ADDR        $remote_addr;
	scgi_var  REMOTE_PORT        $remote_port;
	scgi_var  SERVER_ADDR        $server_addr;
	scgi_var  SERVER_PORT        $server_port;
	scgi_var  SERVER_NAME        $server_name;
	scgi_var    SCRIPT_NAME  $uri;
	scgi_var    PATH_INFO    $uri;
Most important is scgi_pass; - on that IP/Port a WSGI/SCGI server has to listen. For django we have, which we be run like this:
python --projects=/path/to/Django/project/ --settings=settings --host=localhost --port=8080
Django will return the page from the Django project, but it will look like text/plain and not as text/html:
Status: 200 OK
Vary: Cookie
Content-Type: text/html; charset=utf-8
Currently mod_scgi needs first line to look like:
HTTP/1.1 200 OK
So to use it some flup editing is required I guess ;)
blog comments powered by Disqus