Posted on Feb. 22, 2008 at 2:47 P.M.

Developing a site with Django is usually a breeze. You've set up your models, created some views and used some generic views, and you've even created some spiffy templates. Now it's time to publish that site for everyone to see. Now if you're not already familiar with Apache, Lighttpd, or Nginx, you're stuck trying to figure out complicated configuration files and settings directives. "Why can't deployment be just as easy as running the development server?", you scream.

It's tempting to just attempt to use the development server in production. But then you read the documentation (you do read the documentation, right?) and it clearly says:

DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests. (And that’s how it’s gonna stay. We’re in the business of making Web frameworks, not Web servers, so improving this server to be able to handle a production environment is outside the scope of Django.)

Looks like it's time to fire up Apache, right? Wrong. At least, you don't have to.

CherryPy to the Rescue

One of the features that CherryPy touts quite highly is that they include "A fast, HTTP/1.1-compliant, WSGI thread-pooled webserver", however a lesser known fact about that webserver is that it can be run completely independently of the rest of CherryPy--it's a standalone WSGI server.

So let's grab a copy of the CherryPy WSGI webserver:

wget http://svn.cherrypy.org/trunk/cherrypy/wsgiserver/__init__.py -O wsgiserver.py

Now that you've got a copy of the server, let's write a script to start it up. Your choices may vary depending on how many threads you want to run, etc.

import wsgiserver
#This can be from cherrypy import wsgiserver if you're not running it standalone.
import os
import django.core.handlers.wsgi

if __name__ == "__main__":
    os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
    server = wsgiserver.CherryPyWSGIServer(
        ('0.0.0.0', 8000),
        django.core.handlers.wsgi.WSGIHandler(),
        server_name='www.django.example',
        numthreads = 20,
    )
    try:
        server.start()
    except KeyboardInterrupt:
        server.stop()

Consequences

Now you've got the server up and running, lets talk about some consequences of this approach.

  1. This is a multithreaded server. Django is not guaranteed to be completely thread safe. Many people seem to be running it fine in multithreaded environments, but thread safety may break at any time without notice. It might be an interesting project to convert cherrypy.wsgiserver to use processing instead of threading and see how the performance changes.
  2. This server is written in Python, and as with any other Python program, it will be difficult for it to match the speed of pure C. For exactly this reason, mod_wsgi is probably always going to be faster than this solution.
  3. You can have a completely self-contained server environment that can be run on Mac, Windows, and Linux with only Python and a few Python libraries installed. Distributing this wsgiserver.py script along with your Django project (or with a Django app, even) could be a great way of keeping the entire program self-contained.

Conclusion

Would I use this instead of a fully-featured web server like Apache or Nginx? Probably not. I would, however, use it for an intranet which demands more performance and security than the built-in development server. In any case, it's a nice nugget of information to have in your deployment toolbox.

Search

 

Recent Links

  • git-issues: A distributed issue tracker built-in to Git.
  • I predicted this back in March--can't believe a solution has surfaced so soon. It makes so much sense to build in an issue tracker to a revision control system. Since you're working with the code, might as well track the issues in the same system and take advantage of the extra metadata. This is really cool (and as a bonus, it's written in Python) so I hope to see it really grow and flourish!

  • How I Work Daily
  • Daily blog by Kevin Fricovsky. In addition to having some really great content, he has started to post audio interviews with people from the Django community. This is a site to keep an eye on in the coming days and months.

  • django-arcade
  • Demo site for django-arcade, an open source reusable Django app to add new flash games to any django-powered site. Looks very cool for easily creating game portals. It also comes from my future employer.

  • Facebook Chat and Scalability (with Erlang)
  • Eugene Letuchy talks about how they they took Facebook Chat from no users to 70 million users, with the help of Erlang.

  • Simon Willison: The Implications of OpenID
  • I somehow missed this presentation when it came out, but it's an absolutely fantastic overview and defense of OpenID by Simon Willison. If you are in any way interested in what OpenID is and what it can offer, you owe it to yourself to check out this presentation.

  • StupidXML
  • Probably the simplest XML library that I've seen for Python. Sometimes you just want to generate some stupid XML, and this is the perfect tool for the job.

  • See the rest of my links...

Pownce

Badges

  • django badge
  • apache badge
  • GeoURL
  • XFN Friendly
  • Valid HTML 4.01 Transitional