Get Microsoft Silverlight

This blog — and all projects contained within — was made with free/demo software available through the Microsoft Web Platform. Go check it out today, it’s pretty cool.

Get the Microsoft Web Platform.

Django on a Windows Server with IIS

Part of the terms of this project were that we deploy and use a Windows server running IIS for both the blog, and for any other subsite, such as rsstunes.com.

As I’ve mentioned in previous posts, I was pleasantly surprised to see just how easy the Microsoft Web Installer made getting PHP running on Windows. If you’ve got to do it, there’s no better way.

A vast majority of our internally development over the last year has been in PHP. It’s an agile, relatively mature language, and it runs just about anywhere a client could ask it to.

But as we’ve matured as a development team, I’ve been pushing us increasingly towards using Python, and an excellent web framework called Django.

Django, and Python, are most assuredly not supported by the Web Installer, and while I knew I might be shooting myself in the foot, I decided that, for the second version of the rsstunes.com site, we’d use Django, and I’d sort out how to get it running on IIS.

Since the vast majority of Django developers are running a standard Linux stack, there are few, if any good resources out there on getting Django running. There are a few hints, and assorted messages strewn about mailing lists, but nothing authoritative.

After about two weeks of configuration headaches, and crashes, I’ve managed to get a stable, production ready installation of Django running.

Here’s how.

Python.

Before you get started, you need to get a copy of Python running on your Windows server. The easiest way is to download and install the Windows Python 2.6.4 installer from Python.org.

I installed mine at the root of the C: drive under a folder called “python”.

MySQL & Python MySQLdb

For our projects, we develop using MySQL as our database server. If you’re using Postgres, you’re on your own getting everything running.

First, You’ll need to download and install MySQL. There are MSI packages available from MySQL.com. I recommend using MySQL 5.1.

I’d also recommend snagging the MySQL GUI tools. It makes administering the server on Windows infinitely easier.

The final hurdle to a working Django base is to install the Python bindings for MySQL, which, at least on my Snow Leopard installation, can be a real pain. Lucky for us, CodeGood maintains a binary installer for the MySQLDb Python module for Windows. Download and install it.

Optionally, you may want to install the Python Imaging Module, or PIL. Trust me, doing it now will save you some time.

Testing Django

Download the most recent release of Django and install it into C:\python\Lib\site-packages.

Follow the Django Getting Started Tutorial and get a very basic Django project running, just to verify your Python installation is in working order. Chances are, it will be.

IIS & Python

As best I can tell, the standard operating procedure for running Django on a Windows Server is to install Apache and run it under modpython or modwsgi. This seemed fantastically silly to me.

First, Apache, while it runs under Windows just fine, always feels like a kludge when running under Windows. All of the UNIX conventions just stick out like a sore thumb. Seeing that IIS is so stable and awesome at running PHP, why wouldn’t it work to run Django?

The best option seems to be PyISAPIe, an ISAPI plugin for IIS that allows Python scripts to serve web pages. I tried a few other options, such as isapi_wsgi, and just couldn’t keep the server running for longer than one or two requests without a crash.

Download and install 1.1.0-rc4 of PyISAPI and install it. I’d recommend installing it at the root of the C: drive, just like we did for Python.

Your Site Structure

Each Django site will essentially need it’s own copy of the pyisapie.dll file, and it’s own configuration files.

The directory structure I ended up going with broke down to two folders.

Under my inetpub directory, I created a directory called “sites”, which will store each of my Django-powered sites. Each project has it’s own directory under that, and within each of those directories I have a folder for pyisapie and another for my Django project.

In the case of rsstunes.com the structure looks like this:

IIS Directory

The “log” and “public” folders aren’t strictly necessary.

Inside of pyisapie, I have a copy of the DLL file, and the configuration files. Here’s a ZIP archive of pyisapie folder, which you can use to get started.

Next, place your Django project in the python subdirectory.

Configure IIS

We need to register PyISAPIe as being a valid server extension in IIS, and it needs to be setup very specifically if you want to run multiple Django-powered websites.

First, we’ll need to register our site-specific copy of the pyisapie.dll file. Open your IIS Manager, and click on “Web Service Extensions”. Next, click on “Add a new service extension”. Give it a name you’ll recognize (I went with “rsstunes python”), and then click “Add”. Find your site folder, and under pyisapie, click to select the pyisapie.dll file.

Click the checkbox next to “Set extension to Allowed”.

Configure an Application Pool

Due to how PyISAPIe works, you’ll want a separate Application Pool for each of your Django-powered sites. Performance wise, this isn’t great if you’re planning on running dozens of Django sites on one server, but it works great for a handful in my testing.

In your IIS Manager, right-click on Application Pools, and create a new application pool. Again, name it something that will make sense to you.

In terms of settings, I’m still tweaking. For load testing, I use a tool called siege, and check to make sure the server can handle a minimum of 100 requests per second. To achieve this, I set the application pool to recycle workers every 60 minutes, and after 250 requests. You can play with the settings and see what works for you.

Add the Site

Add a site as you would normally under IIS. I set my home directory to that blank “public” directory you saw earlier. It doesn’t actually matter since we’re going to point all requests at our PyISAPIe file.

Under Home Directory, give your application a name, and click “Configuration”. Under Wildcard application maps, click Insert, and browse to your site-specific PyISAPIe.dll file. Make sure “Check that file exists” is unchecked.

Since serving static files with Python is pointless, I’d also go ahead and add a few Virtual Directories for your static files (generally stored in your Django project’s “static” directory), and, if you’re using the Django admin, one for “media”, pointed at C:\python\Lib\site-packages\django\contrib\admin\media.

Lastly, make sure you set the site’s application pool to the one you created earlier.

Edit Isapi.py

The file Isapi.py under “pyisapie/Http” is the actual adapter file PyISAPIe looks for and uses to serve up a request.

You’ll want to do two things.

First, append the full path to your Django project to the system PYTHON_PATH using sys.append, as I’ve done in the example.

Last, you’ll want to set os.environ['DJANGOSETTINGSMODULE'] to your projects settings package.

Start it up

Once you’ve done all that, stop the Application Pool you created and the site. Start the application pool, and then the site. And yes, the order matters.

Visit your site’s URL in a web browser, and you should see your site up and running.

  1. A very helpful guide. Thank you!

    Posted by Andrea G. on December 15th, 2009

  2. Email for verification purposes.

    Comments will be deleted if they are inappropriate.