Gunicorn, uWSGI, or mod_wsgi? What the heck is a WSGI server? Why do I need one? Which one should I choose?
Short answer: Use Gunicorn, unless you are deploying on Windows, in which case use mod_wsgi.
As seen in the picture, the web browser talks to the web server, and the web server in turn talks to the WSGI server. The WSGI server doesn’t talk to your Django project, it imports your Django project. It does something like this:
from django_project.wsgi import application application(args)
from django_project.wsgi import applicationapplication(args)
So, from the operating system’s point of view, your Django project becomes a part of the WSGI server; it is the same process. The way application() is called is standardized by the WSGI specification. The fact that the interface of this function is standardized is what permits you to choose between many different WSGI servers such as Gunicorn, uWSGI, or mod_wsgi, and why each of these can interact with many Python application frameworks like Django or Flask.
mod_wsgi is for Apache only, and I prefer to use a method that can be used with either Apache or nginx. This will make it easier to change the web server, should such a need arise. I also find Gunicorn easier to setup and maintain.
I used uWSGI for a couple of years and was overwhelmed by its features. Many of them duplicate features that already exist in Apache or nginx or other parts of the stack, and thus they are rarely needed. Its documentation is a bit chaotic. The developers themselves admit it: “We try to make our best to have good documentation but it is a hard work. Sorry for that.” I recall hitting problems week after week and spending hours to solve them each time.
Gunicorn, on the other hand, does exactly what you want and no more. It is simple and works fine. So I recommend it unless in your particular case there is a compelling reason to use one of the others.
uWSGI and Gunicorn don’t run in Windows, so if you are deploying on Windows use Apache + mod_wsgi.
This post is largely taken from my book, Deploying Django on a single Debian or Ubuntu server.