This is a good blog entry that covers deploying Django using Nginx and Gunicorn. I’ll give you a quick rundown of what makes all the different technologies important:
Git, or any other version control system, is certainly not required. Why it lends itself to deploying Django projects is that your usually distributing your application by source, i.e. your not compiling it or packaging it as an egg. Usually you’ll organize your Git repository as such that updating your application on the server only requires you to do a checkout of the latest sources–nothing else.
virtualenv and pip
This, again, is not a strict requirement, but I’d strongly suggest you take the time to familiarize yourself with virtualenv and pip if you already haven’t done so, since it’s going to make deploying your Python applications across different runtime environments, local or remote, a breeze.
Basically, your project will need to have at least Django and Gunicorn available on the Python path, possibly even a database driver. What that means is that every time you try to deploy your application somewhere you’ll have to install Python and do the
easy_install dance all over.
virtualenv will redistribute a Python installation, which in turn means that the new Python instance will, by default, have it’s very own Python path configuration relative to the installation. pip is like
easy_install on steroids, since it supports checking out Python dependencies directly from code repositories and supports a requirements file format with which you can install and configure all of your dependencies in one fell swoop.
With virtualenv and pip, all you’d need to do is have a simple text file with all your dependencies that can be parsed with pip and an installed Python distribution on the machine. From there you just do
git checkout repo /app/path; easy_install virtualenv; virtualenv /app/path; ./app/path/scripts/activate; pip install -r /app/path/requirements.txt. Voila, Gunicorn, Django and all other dependencies are then installed and available immediately. When you run the Gunicorn Django script with the Python instance in
/app/path/scripts, then the script will immediately have access to the Gunicorn sources and it will be able to locate your Django project which will have access to Django and other dependencies as well.
Web servers will primarily be used to server static media. Everything else gets proxied to your Gunicorn instance that manages your Django instance, since it’s primary purpose is to host Python WSGI applications and not to act as a general purpose Web server and conversely your Web server doesn’t need to be able to handle Python applications.
Why Nginx is often used is that it’s lightweight and exactly suited for serving static media and proxying requests. It comes with way less bells and whistles than, say, Apache, which makes it all the more easier to configure and maintain, least to mention it’s going to be more resource effective if your already strained.
This is the actual Python application that will manage your Django instance and provide an HTTP interface that exposes it to HTTP clients. It’ll start several worker processes which will all be distinct Python virtual machines loaded with the sources of your application and it’s dependencies. The main Gunicorn process will in turn take charge of managing which worker processes manage which requests for maximum throughput.
The basic principle of wiring Nginx and Gunicorn
The most important thing to observe is that Nginx and Gunicorn are separate processes that you manage independently.
Any other request should be proxied to your Gunicorn instance. It will be configured to listen to HTTP requests on a certain port on the loopback interface, so you’ll using Nginx as a revers proxy to
http://127.0.0.1:8080 for requests to your Django instance.
This is the basic rundown for deploying your Django projects into production that should satisfy the needs of 95% Django projects running out there. While I did reference Nginx and Gunicorn, it’s the usual approach when it comes to setting up any Web server to act as a reverse-proxy to a Python WSGI server.
For the purposes of ‘simple’, I’d use Apache and mod_wsgi: it is well-documented and ‘just works’.
Deploying Django with Apache and mod_wsgi is a tried and tested way to get Django into production.
– Django docs
- Adding forgot-password feature to Django admin site
- Maintain SQL operator precedence when constructing Q objects in Django
- Error "Could not load Boto's S3 bindings."
- How to test a Django on_commit hook without clearing the database?
- Field choices() as queryset?