Django rose to fame when a small US newspaper firm open sourced their application back in 2005. From there, Django has grown into the most widely used Python-based web framework. Still used by companies such as Instagram and Pinterest, the relevancy of Django is still as strong as ever.
Django interfaces to NGINX through a Web Server Gateway Interface (WSGI). For Django, one of the most commonly used WSGI interfaces is uWSGI.
If you haven't installed uWSGI yet, the best way is to install the latest version via pip:
apt-get install python-pip python-dev
pip install uwsgi
We're going to simply use a base install of the latest version of Django, which at the time of writing this blog was 1.10.5.
How to do it...
We'll now configure uWSGI to point to our Django project, which for this example I have located at /var/www/djangodemo. Here's the uwsgi.ini file:
[uwsgi] socket = 127.0.0.1:8000 uid=www-data gid=www-data chdir=/var/www/djangodemo module=djangodemo.wsgi master=True pidfile=/tmp/uwsgi-djangodemo.pid vacuum=True max-requests=5000 daemonize=/var/log/uwsgi/djangodemo.log
For this example, we're also using TCP sockets rather than Unix sockets. Although they're slightly more efficient, having a proper socket makes it much easier for the initial testing phase. If you're hitting limitations (many thousands of concurrent connections), then I'd suggest that you use Unix sockets.
Now for the NGINX configuration, we'll use a separate configuration file (/etc/nginx/conf.d/django.conf) to keep things neat and tidy:
server { listen 80; server_name djangodemo.nginxcookbook.com; access_log /var/log/nginx/djangodemo-access.log combined; location = /favicon.ico { access_log off; log_not_found off; } location /static|/media { root /var/www/djangodemo/; } location / { include uwsgi_params; uwsgi_pass 127.0.0.1:8000; } }
How it works....
The first configuration item we tweak is the favicon:
location = /favicon.ico { access_log off; log_not_found off; }
There's a very famous story of Instagram's first deployment (where they had 10,000 users in the first day) and the load that a missing favicon generated (since Django had to produce the 404 error) caused significant scaling issues.
Next, we serve any of the uploaded and static media directly via NGINX:
location /static|/media { root /var/www/djangodemo/; }
These directories are mapped via the STATIC_ROOT and MEDIA_ROOT configuration lines within the settings.py file for Django. NGINX is very efficient at serving static media, so serving it directly produces as little overhead as possible.
We then map app's all other URL calls via the uwsgi protocol:
location / { include uwsgi_params; uwsgi_pass 127.0.0.1:8000; }
The uWSGI project has a native protocol (called uwsgi and in lower case), which is built into NGINX by default. It's a binary protocol designed to be highly efficient and scalable.
See also
For more information on the issues and best practices refer to the following link:
http://uwsgi-docs.readthedocs.org/en/latest/ThingsToKnow.html