From Development to Production
Running python manage.py runserver is great for development, but production is a different beast. You need a proper web server, secure settings, and a reliable database. This guide covers what you need to ship your Django app to the real world.
The golden rule: never, ever run Django's development server in production. It's single-threaded, insecure, and not designed for real traffic.
Production Settings
Split your settings into base and production files. Key changes for production include setting DEBUG = False, configuring ALLOWED_HOSTS, and using environment variables for secrets.
import os
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME'),
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': os.environ.get('DB_HOST', 'localhost'),
}
}
Never commit secrets to version control. Use environment variables or a secrets manager to keep your credentials safe.
Serving Static Files
In development, Django serves your static files for you. In production, you need to collect them with python manage.py collectstatic and serve them separately.
STATIC_ROOT = '/var/www/yourapp/static/'
STATIC_URL = '/static/'
WhiteNoise is a popular middleware that lets Django serve static files directly without needing nginx for them. It's simple and works well for most sites.
Try it Yourself โGunicorn and Nginx
Gunicorn is a pure-Python WSGI HTTP server that handles multiple worker processes. It's the standard choice for serving Django in production. Nginx sits in front as a reverse proxy, handling SSL termination, static files, and load balancing.
A basic Nginx config proxies requests to Gunicorn, serves your static files directly (much faster), and handles HTTPS with Let's Encrypt certificates. Gunicorn binds to localhost and Nginx exposes your app to the world.
Database in Production
SQLite is fine for development but not for production. Switch to PostgreSQL or MySQL. Both are battle-tested with Django and handle concurrent connections properly.
Run python manage.py migrate on your production database after deploying. Set up regular backups, connection pooling with PgBouncer if needed, and monitor your database performance from day one.