Mike Slinn
Mike Slinn

Investigating a Django-Oscar Production Setup

Published 2021-04-13. Last modified 2021-04-16.
Time to read: about 2 minutes.

This article is categorized under Django, Django-Oscar.

In this post I share my progress setting up the Django-Oscar webapp that I've been working on for production. The app is nowhere near production-ready, so this post will actually discuss what I learned setting up a staging server.

Apache httpd vs. Nginx

Django is written in Python, so there are only two protocols that bridge Python code and web servers. The Python / httpd protocol that seems to have the best support and stability is wsgi.

The two top choices for a web server that supports wsgi are Apache httpd and nginx. Both Apache httpd and nginx (pronounced engine-x) are a free, open-source, high-performance HTTP servers and reverse proxies. I have used them before. They are both solid. Apache is decades older. All the cool kids are using nginx these days.

The Django documentation does not mention nginx. At first, the lack of official support by Django for nginx concerned me somewhat, but my interactions with Django maintainers so far have shown me that there is a significant faction of those maintaners that is resistant to change of any kind.

In looking for defensible reasons for choosing one http server over the other, I found some important information in the uWSGI documentation:

The uWSGI module is included in the official Nginx distribution since version 0.8.40. A version supporting Nginx 0.7.x is maintained in the uWSGI package. This is a stable handler commercially supported by Unbit.

The Apache2 mod_uwsgi module was the first web server integration module developed for uWSGI. It is stable but could be better integrated with the Apache API. It is commercially supported by Unbit.

Since uWSGI 0.9.6-dev a second Apache2 module called mod_Ruwsgi is included. It’s more Apache API friendly. mod_Ruwsgi is not commercially supported by Unbit.

During the 1.2 development cycle, another module called mod_proxy_uwsgi has been added. In the near future this should be the best choice for Apache-based deployments.

AppDynamics published A Performance Analysis of Python WSGI Servers, and their conclusions were:

  • We were sorely disappointed with uWSGI.
  • Gunicorn: A good, consistent performer for medium loads.
  • mod_wsgi: Multi-threaded server with all cores fully pegged the entire time. (Highest CPU usage of all contenders benchmarked.)

In Digital Ocean’s article Django Server Comparison: The Development Server, Mod_WSGI, uWSGI, and Gunicorn:

Drawbacks to Gunicorn are much the same as uWSGI, though I personally have found Gunicorn to be more easily configurable than uWSGI. It still isn’t as quick or simple to configure and set up as using mod_wsgi with Apache, but on a performance level there is no comparison. (Gunicorn outperforms mod_wsgi.)

Kurt Griffiths wrote a terrific benchmark back in 2012. 9 years later, I wonder how results might have changed?

However, there may be a much more interesting option: hosting Django webapps as lambda functions.

Digital Ocean hosts a nice nginx / Django configuration tool that works with any server, not necessarily at Digital Ocean.