Of course! This is a very common and important topic for developers working in a Windows Server environment. Here’s a comprehensive guide on running a Django application on IIS (Internet Information Services).
Overview: Why Run Django on IIS?
IIS is Microsoft's web server, and it's the default web server for Windows Server. While many developers prefer to run Django on a Linux stack with Nginx and Gunicorn, there are several reasons you might choose to run it on IIS:
- Corporate Environment: Your company's infrastructure is already Windows-based.
- Legacy Systems: You need to integrate with other Windows-based services or applications.
- Simplicity: For some, managing a single Windows server (IIS + Python) can be simpler than a multi-server Linux setup.
- Active Directory Integration: Seamless integration with Windows authentication.
The core challenge is that IIS is a native Windows application and doesn't know how to run Python code directly. It needs a bridge, which is where WSGI comes in.
The Core Concept: IIS + WSGI
The standard way to run Python web applications on any web server is through the Web Server Gateway Interface (WSGI). The process looks like this:
- IIS receives an HTTP request from a user's browser.
- IIS passes this request to a WSGI Server.
- The WSGI Server (e.g., Gunicorn, uWSGI) loads your Django application.
- The WSGI Server calls the appropriate Django view, processes the request, and gets back a response.
- The WSGI Server passes the response back to IIS.
- IIS sends the final response to the user's browser.
For IIS, the most common and recommended WSGI server is Gunicorn.
Step-by-Step Guide: Deploying Django on IIS
This guide assumes you have a working Django project and administrative access to a Windows Server.
Step 1: Install Python on the Server
- Download the latest Python installer for Windows from the official Python website.
- Run the installer. Crucially, check the box that says "Add Python to PATH". This will save you a lot of headaches.
- Open a new Command Prompt or PowerShell and verify the installation by running:
python --version pip --version
Step 2: Install Your Project's Dependencies
In the command prompt, navigate to the directory where you will place your Django project (e.g., C:\inetpub\wwwroot\myproject). It's a best practice to use a virtual environment.
# Create a virtual environment python -m venv venv # Activate the virtual environment .\venv\Scripts\activate # Install your project dependencies (from your requirements.txt file) pip install -r requirements.txt
Important Dependency: You will need to install a WSGI server. Gunicorn is a great choice.
pip install gunicorn
Step 3: Install the IIS URL Rewrite Module
This module is essential for IIS to correctly forward requests to your WSGI application. It's a standard component for modern IIS deployments.
- Download the URL Rewrite Module from the official IIS website.
- Run the installer. It will integrate directly with your Server Manager.
Step 4: Configure IIS to Host Your Django App
Now, let's set up the website in IIS.
-
Create a Website:
- Open Internet Information Services (IIS) Manager.
- In the "Connections" pane, right-click on Sites and select Add Website....
- Site name: Give your site a name (e.g.,
MyDjangoApp). - Physical path: Point this to the root directory of your Django project (e.g.,
C:\inetpub\wwwroot\myproject). - Port: Choose a port (e.g.,
8080). - Click OK.
-
Configure Handler Mappings:
- Select your new site in the Connections pane.
- In the center pane, double-click on Handler Mappings.
- In the "Actions" pane on the right, click Add Module Mapping....
- Request path:
- Module:
FastCgiModule - Executable: Browse to your Python interpreter. This is usually inside your virtual environment:
C:\inetpub\wwwroot\myproject\venv\Scripts\python.exe - Name: Give it a name (e.g.,
Python FastCGI). - Click Request Restrictions..., uncheck "Invoke handler only if request is mapped to", and click OK.
- Click OK again to save the module mapping. You will be prompted to allow IIS to configure
web.configfiles. Allow it.
Step 5: Create a web.config File
This file tells IIS how to handle your application. Create a file named web.config in the root directory of your Django project (C:\inetpub\wwwroot\myproject) and add the following content.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<!-- This section handles static files (CSS, JS, images) -->
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" />
</staticContent>
<!-- This section is for URL rewriting -->
<rewrite>
<rules>
<!-- This rule redirects all non-static requests to the Django app -->
<rule name="StaticFiles" stopProcessing="true">
<match url="^(static)/(.*)$" />
<action type="None" />
</rule>
<rule name="DjangoApplication" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="index.wsgi" />
</rule>
</rules>
</rewrite>
<!-- This section configures FastCGI to run your WSGI script -->
<handlers>
<add name="Python FastCGI" path="index.wsgi" verb="*" modules="FastCgiModule" scriptProcessor="C:\inetpub\wwwroot\myproject\venv\Scripts\python.exe" resourceType="Unspecified" requireAccess="Script" />
</handlers>
</system.webServer>
<system.web>
<compilation debug="false" />
<customErrors mode="Off" />
</system.web>
</configuration>
Explanation of web.config:
<rewrite>: This is the magic. It checks if the requested URL is a file (likestatic/css/style.css). If it's not, it rewrites the URL toindex.wsgi.<handlers>: This tells IIS that any request forindex.wsgi(or any other file, because of thepath="*"mapping we made earlier) should be handled by theFastCgiModule, using thepython.exein our virtual environment.
Step 6: Create the WSGI Entry Point (index.wsgi)
In the root of your Django project, create a file named index.wsgi. This file is the entry point for your application.
import os
import sys
# Add the project root to the Python path
# Assumes your manage.py is in the same directory as this wsgi file
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# Set the DJANGO_SETTINGS_MODULE environment variable
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
# Import Django and configure the application
import django
django.setup()
# Import the WSGI application
from django.core.wsgi import get_wsgi_application
# This is the final WSGI application that IIS will use
application = get_wsgi_application()
Note: Replace 'myproject.settings' with the actual path to your project's settings.py file (e.g., 'my_django_app.settings').
Step 7: Final Steps and Testing
- Check Permissions: The IIS user (by default,
IIS_IUSRS) needs read and execute permissions on your project folder and its contents. Right-click the project folder, go toProperties->Security->Edit->Add, and typeIIS_IUSRS. Give it "Read & execute" and "List folder contents" permissions. - Restart IIS: Open Command Prompt as an Administrator and run:
iisreset /restart
- Browse to Your Site: Open a web browser and navigate to
http://localhost:8080(or whatever hostname and port you configured in IIS).
You should see your Django application!
Common Problems and Solutions
- HTTP Error 500.19 - Internal Server Error: This is usually a permissions issue. Ensure the
IIS_IUSRSuser has the correct permissions on your project directory. It can also be caused by a malformedweb.configfile. [Errno 2] No such file or directory: 'django-admin.py'orpython.exenot found: This means the path to your Python executable in the Handler Mapping orweb.configis incorrect. Double-check the path.- Application not starting: Check the IIS error logs. You can find them in
C:\inetpub\logs\LogFiles\W3SVC1\. These logs often provide specific error messages from the WSGI server. - Static files (CSS, JS) not loading: This is a classic Django + IIS issue. The
<rewrite>section inweb.configis designed to fix this by telling IIS to serve files from thestaticdirectory directly without sending them to Django.
Modern Alternative: The IIS Python Module
For a more integrated (and potentially higher-performance) solution, you can use the IIS Python Module. This is a native module that embeds Python directly within IIS, bypassing the need for an external WSGI server like Gunicorn.
Pros:
- Potentially better performance as it avoids the overhead of an external process.
- Simpler setup in some ways (no need to manage a separate WSGI server process).
Cons:
- Less mature and widely adopted than the WSGI/FastCGI approach.
- Configuration is different and can be more complex.
If you are starting a new project and want to explore this, you would install the module from PyPI (pip install iis) and follow its specific documentation for configuring your Django application within it. For most production deployments, however, the Gunicorn + FastCGI method remains the more battle-tested and standard approach.
