Production Deployment
Deploy Django to production with Docker, Gunicorn (WSGI server), Nginx (reverse proxy), PostgreSQL, and Redis. Learn environment-based settings, static files, and automated deployment with GitHub Actions.
40 min•By Priygop Team•Last updated: Feb 2026
Production Stack
- Gunicorn — WSGI server: gunicorn myapp.wsgi:application --workers 4 --bind 0.0.0.0:8000. Never use Django's runserver in production
- Nginx — Reverse proxy: forwards requests to Gunicorn, serves static files directly, handles SSL termination
- PostgreSQL — Production database. Use dj-database-url: DATABASE_URL=postgres://user:pass@host/db
- Redis — Caching (cache.set/get), Celery broker for async tasks, Django sessions
- Environment variables — python-decouple: SECRET_KEY=config('SECRET_KEY'). Never hardcode secrets
- DEBUG=False — Required for production. Enables security headers, disables debug pages
- ALLOWED_HOSTS — List of allowed domain names: ['priygop.com', 'www.priygop.com']
- collectstatic — python manage.py collectstatic copies all static files to STATIC_ROOT for Nginx to serve
Docker Compose Setup
Example
# Dockerfile
FROM python:3.12-slim
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", "myapp.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
# docker-compose.yml
services:
db:
image: postgres:16
environment:
POSTGRES_DB: myapp
POSTGRES_USER: myapp
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
web:
build: .
env_file: .env
depends_on: [db, redis]
volumes:
- static_volume:/app/staticfiles
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- static_volume:/app/staticfiles
depends_on: [web]
volumes:
postgres_data:
static_volume:
# .env (never commit to git!)
SECRET_KEY=your-secret-key-here
DEBUG=False
ALLOWED_HOSTS=yourdomain.com
DATABASE_URL=postgres://myapp:password@db/myapp
REDIS_URL=redis://redis:6379/0