Django on nginx

Check out the new site at https://rkblog.dev.

From the wikipedia: Nginx (engine x) - small, but very powerful and efficient web server created by Igor Sysoev for large Russian web company Rambler and kindly provided by open-source community. This server can be used as standalone HTTP server and as reverse proxy server before some Apache or another “big” server” to reduce load to backend server by many concurrent HTTP-sessions. As standalone web server, nginx can easily handle huge http-load on static files (images, html-pages, etc).
Project site
Nginx - Small, But Very Powerful and Efficient Web Server
Typical Configurations Overview For Nginx HTTP(S) Reverse Proxy/Web Server
Nginx, my new favorite front end for mongrel cluster
High-Performance Ruby On Rails Setups Test: mongrel vs lighttpd vs nginx
Django and nginx (russian)
Cherokee, PHP and nginx


The most common use for nginx would be as a reverse proxy server which would balance the load between few running lighttpd/cherokee/apache processes with your django web site. nginx also supports fastcgi so it can be set to use django "directly".

Nginx instalation

- check your distributions/os repositories. It there isn't any nginx package compile it from source, check ./configure --help for extra params.
- after installation nginx config files should be in /etc/nginx/ and you should be able to start it by running:
/etc/something/nginx start


Nginx serving static files and django application by FastCGI

Use this nginx.conf as a template for your site:
user  apache apache;

worker_processes  2;

error_log /var/log/nginx/error_log info;

events {
	worker_connections  1024;
	use epoll;
}

http {
	include		/etc/nginx/mime.types;
	default_type	application/octet-stream;

	log_format main
		'$remote_addr - $remote_user [$time_local] '
        	'"$request" $status $bytes_sent '
		'"$http_referer" "$http_user_agent" '
		'"$gzip_ratio"';

	client_header_timeout	10m;
	client_body_timeout	10m;
	send_timeout		10m;

	connection_pool_size		256;
	client_header_buffer_size	1k;
	large_client_header_buffers	4 2k;
	request_pool_size		4k;

	gzip on;
	gzip_min_length	1100;
	gzip_buffers	4 8k;
	gzip_types	text/plain;

	output_buffers	1 32k;
	postpone_output	1460;

	sendfile	on;
	tcp_nopush	on;
	tcp_nodelay	on;

	keepalive_timeout	75 20;

	ignore_invalid_headers	on;
	index index.html;

	server {
		listen 80;
		server_name localhost;
		# site_media - folder in uri for static files
		location /site_media  {
			root /path/to/media/folder;
			}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js|mov) {
  access_log   off; # po co mi logi obrazków :)
  expires      30d; 
}
		location / {
			# host and port to fastcgi server
			fastcgi_pass 127.0.0.1:8080;
			fastcgi_param PATH_INFO $fastcgi_script_name;
			fastcgi_param REQUEST_METHOD $request_method;
			fastcgi_param QUERY_STRING $query_string;
			fastcgi_param CONTENT_TYPE $content_type;
			fastcgi_param CONTENT_LENGTH $content_length;
			fastcgi_pass_header Authorization;
			fastcgi_intercept_errors off;
			}
		access_log	/var/log/nginx/localhost.access_log main;
		error_log	/var/log/nginx/localhost.error_log;
		}
	}
}
The only thing that you need to change is:
server_name localhost;
# site_media - folder in uri for static files - 
location /site_media  {
	root /path/to/media/folder;
	}
- You need also to start django fastcgi server (from the project folder):
python manage.py runfcgi host=127.0.0.1 port=8080 --settings=settings
If you need to add something to pythonpath:
python manage.py runfcgi host=127.0.0.1 port=8080 --settings=settings --pythonpath=/a/path/to/somewhere/
- Start nginx server. Now you should see under http://localhost your web site

Reverse proxy on Django+SCGI+Cherokee

So we have a working Django+SCGI+Cherokee. We will use nginx as a reverse proxy that will redirect all trafic to that trio. Edit cherokee.conf and change:
Port 80
- To:
Port 8000
- Start everything (djang-scgi.py, cherokee), check if http://localhost:8000/ works. It should
- Edit nginx.conf:
user  apache apache;

worker_processes  2;

error_log /var/log/nginx/error_log info;

events {
	worker_connections  1024;
	use epoll;
}

http {
	include		/etc/nginx/mime.types;
	default_type	application/octet-stream;

	log_format main
		'$remote_addr - $remote_user [$time_local] '
        	'"$request" $status $bytes_sent '
		'"$http_referer" "$http_user_agent" '
		'"$gzip_ratio"';

	client_header_timeout	10m;
	client_body_timeout	10m;
	send_timeout		10m;

	connection_pool_size		256;
	client_header_buffer_size	1k;
	large_client_header_buffers	4 2k;
	request_pool_size		4k;

	gzip on;
	gzip_min_length	1100;
	gzip_buffers	4 8k;
	gzip_types	text/plain;

	output_buffers	1 32k;
	postpone_output	1460;

	sendfile	on;
	tcp_nopush	on;
	tcp_nodelay	on;

	keepalive_timeout	75 20;

	ignore_invalid_headers	on;
	index index.html;

 upstream django {
        server 127.0.0.1:8000;
    }


	server {
		listen 80;
		server_name localhost;
		location / {
			proxy_pass  http://django;
			proxy_redirect  default;
			}
		access_log	/var/log/nginx/localhost.access_log main;
		error_log	/var/log/nginx/localhost.error_log;
		}
	}
}
There are two interesting elements:
 upstream django {
        server 127.0.0.1:8000;
    }
 upstream LABEL {
        server IP:PORT;
        server IP:PORT;
        server IP:PORT;
    }
Upstream defines set of servers on which the requests will be split. In our basic setup we have one cherokee, running on port 8000. Next we have:
location / {
	proxy_pass  http://django;
	}
location / {
	proxy_pass  http://LABEL;
	}
Will redirect the trafic on / to set of servers defined in one of upstream blocks.
- Start nginx and visit http://localhost/ - your site should run without any problems.
RkBlog

Programming in Python, 14 July 2008


Check out the new site at https://rkblog.dev.
Comment article
Comment article RkBlog main page Search RSS Contact