How to Run Django as a Windows Service with Waitress and PyWin32
etting up a Django project to run as a Windows service can help ensure that your application stays online and automatically restarts after system reboots. This guide walks you through setting up Django as a Windows service using **Waitress** (a production-ready WSGI server) and **PyWin32** for managing the service. We'll also cover common problems, like making sure the service starts and stops correctly.

Setting up a Django project to run as a Windows service can help ensure that your application stays online and automatically restarts after system reboots. This guide walks you through setting up Django as a Windows service using Waitress (a production-ready WSGI server) and PyWin32 for managing the service. We'll also cover common problems, like making sure the service starts and stops correctly.
The Plan
We'll be doing the following:
- Set up Django to run as a Windows service using PyWin32.
- Use Waitress to serve the Django application.
- Handle service start/stop gracefully.
- Troubleshoot common issues that can pop up.
Step 1: Install What You Need
You'll need to install Django, Waitress, and PyWin32. Run these commands to install the necessary packages:
pip install django waitress pywin32
After installing PyWin32, run the following command to finish the installation:
python -m pywin32_postinstall
This step ensures the necessary Windows files for PyWin32 are in place.
Step 2: Write the Python Service Script
To create the Windows service, we’ll write a Python script that sets up the service and runs the Django app through Waitress.
Create a file named django_service.py in your Django project directory (where manage.py is located), and paste the following code:
import os
import sys
import win32service
import win32serviceutil
import win32event
from waitress import serve
from django.core.wsgi import get_wsgi_application
import logging
## Set up logging for debugging
logging.basicConfig(
filename='C:\\path\\to\\logs\\django_service.log',
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
class DjangoService(win32serviceutil.ServiceFramework):
_svc_name_ = "DjangoWebService"
_svc_display_name_ = "Django Web Service"
_svc_description_ = "A Windows service running a Django web server using Waitress."
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.running = True
logging.info("Initializing Django service...")
try:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project_name.settings')
self.application = get_wsgi_application()
except Exception as e:
logging.error(f"Error initializing WSGI application: {e}")
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
self.running = False
logging.info("Stopping Django service...")
def SvcDoRun(self):
logging.info("Service is running...")
serve(self.application, host='0.0.0.0', port=8000)
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(DjangoService)
What’s Happening in the Script:
- Logging: We set up logging to help debug issues. All logs go to
django_service.log. - WSGI Application: Django’s
get_wsgi_application()is used to initialize the app. - Waitress: We serve Django using Waitress, which is a good production-ready server.
- Service Methods:
SvcStop(): Handles stopping the service gracefully.SvcDoRun(): Runs the Waitress server.
Step 3: Install the Service
Once the script is ready, you need to install it as a Windows service. Run this command in the directory where your django_service.py is located:
python django_service.py install
This registers your Django application as a Windows service.
Note:
Make sure to run this command as an administrator. Services need elevated privileges to install properly.
Step 4: Start the Service
Now that the service is installed, you can start it by running:
python django_service.py start
Alternatively, you can go to the Windows Services panel (services.msc), find "Django Web Service," and start it from there.
Step 5: Troubleshooting Common Errors
Error 1066: Service-Specific Error
This error usually happens when something crashes during the service startup. To fix it:
- Check Logs: Look at
django_service.logfor any errors. - Check Django Config: Make sure that
DJANGO_SETTINGS_MODULEis set correctly.
Error 1053: Service Did Not Respond in Time
This happens when the service takes too long to start. You can try:
- Optimizing Django Startup: Check if your app takes too long to start (e.g., database connections).
- Check Waitress Config: Ensure that the server is set up properly.
Logs Not Generated
If logs aren’t showing up:
- Ensure the directory
C:\\path\\to\\logsexists. - Make sure the service has permission to write to that directory.
- Double-check that logging is set up before the service starts.
Step 6: Stopping the Service Gracefully
Stopping services cleanly is essential to avoid crashes or stuck processes. In the SvcStop method, we signal the server to stop by setting self.running = False.
If this still doesn’t stop the service cleanly, you can add os._exit(0) to force an exit, but this should be a last resort. Try to allow the application to shut down properly if possible.
Step 7: Configuring Allowed Hosts in Django
Before you go live, ensure that the ALLOWED_HOSTS setting in settings.py is configured properly. It should include the domain or IP of your server:
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'your-domain.com']
This ensures Django only accepts requests from specified hosts, which is crucial for security.
Step 8: Package it with PyInstaller (Optional)
If you want to package everything into a single executable, you can use PyInstaller. Here’s how:
First, install PyInstaller:
pip install pyinstaller
Then, create the executable:
pyinstaller --onefile django_service.py
This will create a standalone executable in the dist folder that you can deploy to other Windows machines.
Conclusion
By following this guide, you’ve successfully set up Django to run as a Windows service using Waitress and PyWin32. You’ve also learned how to:
- Install and run the service.
- Debug common service-related errors.
- Ensure a clean shutdown for the service.
- Configure Django’s
ALLOWED_HOSTSfor production.
With this setup, your Django app will run efficiently as a background service, ensuring it stays available even after reboots.
For more information on the topics covered in this blog, check out these resources:
From the team at Nife
Deploy your next app in minutes, not days.
Nife is a multi-cloud edge platform that lets you deploy, scale, and manage applications globally without the infrastructure headache.