Feb 22, 2008
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.
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()
Now you've got the server up and running, lets talk about some consequences of this approach.
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.