Deploying Django Apps
Production Django with Gunicorn, Nginx, static files via WhiteNoise, and Postgres on VPS or container.
PlatformsAdvanced
Why
Django's batteries-included approach (ORM, admin, auth) accelerates development, and Gunicorn+Nginx is the proven production stack. WhiteNoise serves static files without needing a separate CDN.
Platform-as-a-Service adoption grew 24% in 2024 as teams shift from VM management to git-push deploys. the cloud infrastructure market reached $330B in 2024, growing 22% year-over-year (Synergy Research), and PaaS layers capture the majority of new workloads.
When
Use Django for content-heavy apps with admin needs, ORM-driven CRUD, and Python teams. Avoid for microservices — Flask/FastAPI are lighter.
How
1. WSGI server — gunicorn myproject.wsgi:application -w 4 -b 0.0.0.0:8000
2. Nginx — reverse proxy to gunicorn, serve static/media, TLS
3. Static files — python manage.py collectstatic, WhiteNoise middleware
4. DB — Postgres, set DATABASE_URL, run migrations on deploy
5. Docker — python:3.12-slim, gunicorn, multi-stage
6. Env — DJANGO_SETTINGS_MODULE, DEBUG=False, ALLOWED_HOSTS
7. ASGI — for websockets/async use daphne or uvicorn with channels
Example
# Dockerfile
FROM python:3.12-slim AS base
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN python manage.py collectstatic --noinput
EXPOSE 8000
CMD ["gunicorn", "myproject.wsgi:application", "-w", "4", "-b", "0.0.0.0:8000"]
# nginx.conf
upstream django { server app:8000; }
server {
listen 80;
location /static/ { alias /app/staticfiles/; }
location / { proxy_pass http://django; proxy_set_header Host $host; }
}
# settings.py — production
MIDDLEWARE = ["whitenoise.middleware.WhiteNoiseMiddleware", ...]
STATICFILES_STORAGE = "whitenoise.storage.CompressedStaticFilesStorage"
DEBUG = False
ALLOWED_HOSTS = ["myapp.com"]
Common Problems
- ⚠Static files 404 in production — forgot collectstatic or WhiteNoise middleware config
- ⚠DEBUG=True in production — security risk, leaks stack traces and settings
- ⚠ALLOWED_HOSTS mismatch — 400 Bad Request, set to your domain or ['*'] for testing
Best Practices
- ✓Use WhiteNoise for static files — eliminates need for Nginx static serving or CDN in simple deploys
- ✓Run migrations as a separate deploy step, not in CMD — allows rollback without DB changes
- ✓Set up health checks and graceful shutdown — handle SIGTERM to drain in-flight requests before exit