Django Docker Compose Production Deployment - AI-Optimized Guide
Critical Failure Modes and Solutions
Container Exit Scenarios
- Immediate container exit: Missing environment variables cause
KeyError
ordjango.core.exceptions.ImproperlyConfigured
- SECRET_KEY errors: Container starts, Django reads settings, hits missing
SECRET_KEY
, exits with code 1 - Windows line endings:
.env.prod
file with\r\n
breaks variable parsing - fix withdos2unix .env.prod
- Permission issues: Container cannot read env file - check file permissions
Database Connection Failures
- "relation does not exist": Django queries non-existent tables - run migrations after container startup
- Service communication: Use service names (
db
) notlocalhost
/127.0.0.1
in connection strings - Connection timeouts: Add health checks to
depends_on
configuration - Version incompatibility: PostgreSQL version changes require data volume cleanup or migration
Static File Issues
- 404 errors on CSS/JS: Forgot to run
collectstatic
after deployment - Shared volume mounting: Ensure
static_volume
mounted in bothweb
andnginx
services - Cache problems: Aggressive caching headers (
expires 1y
) serve old files after changes
Production Architecture Requirements
Essential Components
- Gunicorn: Replaces Django's single-threaded
runserver
with multi-process workers - PostgreSQL: MVCC prevents write-blocking, supports connection pooling and advanced indexing
- Nginx: Serves static files directly, handles client connection buffering
- Docker Compose: Manages multi-container applications with service dependencies
Performance Specifications
- Gunicorn workers:
(2 × CPU cores) + 1
starting formula - Worker recycling:
--max-requests 1000
prevents memory leak accumulation - Database connections: Monitor with
SELECT count(*) FROM pg_stat_activity;
- Memory monitoring: Use
docker stats
to catch resource growth early
Configuration Requirements
Security Settings (Production Django)
DEBUG = False
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
Database Configuration
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
interval: 30s
timeout: 10s
retries: 5
Nginx Optimization
location /static/ {
alias /home/app/web/staticfiles/;
expires 1y;
add_header Cache-Control "public, immutable";
}
client_max_body_size 100M;
Resource Limits and Scaling
Container Resource Constraints
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
PostgreSQL Tuning
environment:
- POSTGRES_SHARED_PRELOAD_LIBRARIES=pg_stat_statements
- POSTGRES_MAX_CONNECTIONS=100
- POSTGRES_SHARED_BUFFERS=256MB
Critical Deployment Commands
Initial Setup Sequence
# Build with no cache (10+ minutes first time)
docker-compose -f docker-compose.prod.yml build --no-cache
# Start services
docker-compose -f docker-compose.prod.yml up -d
# Wait for database ready signal
docker-compose -f docker-compose.prod.yml logs -f db
# Run migrations
docker-compose -f docker-compose.prod.yml exec web python manage.py migrate --noinput
# Collect static files
docker-compose -f docker-compose.prod.yml exec web python manage.py collectstatic --no-input --clear
Backup and Recovery
# Database backup
docker-compose -f docker-compose.prod.yml exec db pg_dump -U $DB_USER $DB_NAME > backup_$(date +%Y%m%d_%H%M%S).sql
# Database restore
docker-compose -f docker-compose.prod.yml exec -T db psql -U $DB_USER $DB_NAME < backup.sql
Memory Leak Prevention
Worker Management
- Max requests: Set
--max-requests 1000
to restart workers before memory accumulation - Connection age: Avoid high
CONN_MAX_AGE
values that cause connection leaks - Monitoring: Use
docker stats
to track memory growth patterns
Critical Indicators
- Memory usage above 90% indicates worker recycling issues
- Database connection count should drop when traffic decreases
- Worker process count should remain stable under load
Common Error Messages and Fixes
Database Errors
FATAL: sorry, too many clients already
→ CheckCONN_MAX_AGE
and connection poolingProgrammingError: relation "django_session" does not exist
→ Run migrationsdatabase files are incompatible with server
→ PostgreSQL version change requires data migration
Container Errors
network django_default not found
→ Rundocker network create django_default
ECONNREFUSED
→ Service reachable but not accepting connections (still starting)KeyError: 'SECRET_KEY'
→ Missing environment variables in.env.prod
Performance Issues
- Slow responses → Increase worker count or timeout values
- Memory growth → Enable worker recycling and monitor connection leaks
- Static file 404s → Run
collectstatic
and verify volume mounting
Security Best Practices
Environment Variable Management
- Never commit
.env.prod
to version control - Use
docker secret create
for sensitive data - Generate strong
SECRET_KEY
with Django'sget_random_secret_key()
Container Security
- Create non-root users:
adduser --system app
- Switch user context:
USER app
- Set proper directory ownership:
chown -R app:app $APP_HOME
Network Security
- Implement HTTPS redirection
- Configure security headers in Nginx
- Use proper SSL certificate management
Monitoring and Maintenance
Health Checks
# Service status
docker-compose -f docker-compose.prod.yml ps
# Resource usage
docker stats
# Application logs
docker-compose -f docker-compose.prod.yml logs --tail=50
Database Maintenance
# Connection monitoring
docker-compose -f docker-compose.prod.yml exec db psql -U $DB_USER -d $DB_NAME -c "SELECT * FROM pg_stat_activity;"
# Database size check
docker-compose -f docker-compose.prod.yml exec db psql -U $DB_USER -d $DB_NAME -c "SELECT pg_size_pretty(pg_database_size('$DB_NAME'));"
Performance Thresholds
Critical Limits
- UI breaks: 1000+ spans make debugging distributed transactions impossible
- Memory per worker: 2GB indicates serious memory leaks requiring immediate worker recycling
- Database connections: Should not exceed
max_connections
setting under normal load - Response time degradation: Timeout issues often indicate query optimization needs, not timeout increases
Scaling Indicators
- Worker CPU utilization consistently above 80%
- Database connection pool exhaustion
- Static file serving latency increasing
- Memory usage growth patterns over time
Troubleshooting Decision Tree
Container Won't Start
- Check logs with
docker-compose logs web
- Verify environment variables in
.env.prod
- Confirm file permissions and line endings
- Test service networking with
ping
between containers
Database Issues
- Verify PostgreSQL health check passes
- Check connection string service names
- Confirm migrations ran successfully
- Monitor connection counts and query performance
Static File Problems
- Verify
collectstatic
execution - Check volume mounting in both services
- Confirm Nginx configuration paths
- Test cache headers and browser behavior
Performance Degradation
- Monitor worker processes and memory usage
- Check database query performance
- Verify connection pooling configuration
- Analyze resource utilization patterns
This guide provides actionable intelligence for production Django deployments, focusing on failure prevention, performance optimization, and operational reliability rather than basic setup instructions.
Useful Links for Further Investigation
Resources for Mastery
Link | Description |
---|---|
Docker Compose Documentation | Complete reference for Docker Compose configuration, networking, and deployment options. Essential for understanding service definitions and production configurations. |
Django Deployment Documentation | Django's official deployment guide covering production settings, security considerations, and performance optimization techniques. |
PostgreSQL Docker Hub | Official PostgreSQL container documentation including environment variables, initialization scripts, and configuration options for containerized databases. |
Nginx Docker Hub | Official Nginx container documentation with configuration examples, volume mounting, and reverse proxy setup instructions. |
Cookiecutter Django | Battle-tested Django project template with Docker support, production configurations, and security best practices. Includes Celery, Redis, and comprehensive documentation. |
Django Docker Example by Nick JJ | Minimal but complete Django Docker setup focused on production deployment. Clean architecture without unnecessary complexity, ideal for learning core concepts. |
TestDriven.io Django Docker Tutorial | Complete tutorial repository demonstrating Django containerization with Postgres, Gunicorn, and Nginx. Includes development and production configurations. |
Django Security Documentation | Comprehensive security checklist covering HTTPS, CSRF protection, SQL injection prevention, and other critical security considerations for Django applications. |
Docker Security Best Practices | Official Docker security guidelines including non-root users, image scanning, secrets management, and container isolation techniques. |
OWASP Django Security | Open Web Application Security Project's Django-specific security recommendations and vulnerability prevention techniques. |
Better Stack Infrastructure Monitoring | Application performance monitoring and log management specifically designed for containerized Django applications with Docker integration. Their 2025 Django Docker guide aligns with the practices in this tutorial. |
Gunicorn Documentation | Complete WSGI server documentation covering worker configuration, performance tuning, and deployment strategies for production Django applications. |
Sentry Error Tracking | Real-time error tracking and performance monitoring for Django applications. Provides detailed error reports and performance insights for production deployments. |
Django Forum Deployment Category | Active community discussions about Django deployment challenges, solutions, and best practices. Valuable for troubleshooting specific issues. |
Stack Overflow Django Tag | Community-driven discussions, tutorials, and troubleshooting help for Django developers, including containerization and deployment topics. |
Docker Official Django Blog | Docker's own 2025 guide to Django containerization, covering modern best practices and recent developments in Django-Docker integration. |
Related Tools & Recommendations
GitOps Integration Hell: Docker + Kubernetes + ArgoCD + Prometheus
How to Wire Together the Modern DevOps Stack Without Losing Your Sanity
Kafka + MongoDB + Kubernetes + Prometheus Integration - When Event Streams Break
When your event-driven services die and you're staring at green dashboards while everything burns, you need real observability - not the vendor promises that go
RAG on Kubernetes: Why You Probably Don't Need It (But If You Do, Here's How)
Running RAG Systems on K8s Will Make You Hate Your Life, But Sometimes You Don't Have a Choice
PostgreSQL vs MySQL vs MariaDB vs SQLite vs CockroachDB - Pick the Database That Won't Ruin Your Life
competes with mariadb
MongoDB Alternatives: Choose the Right Database for Your Specific Use Case
Stop paying MongoDB tax. Choose a database that actually works for your use case.
MongoDB vs PostgreSQL vs MySQL: Which One Won't Ruin Your Weekend
integrates with postgresql
Podman Desktop - Free Docker Desktop Alternative
competes with Podman Desktop
Python Performance Disasters - What Actually Works When Everything's On Fire
Your Code is Slow, Users Are Pissed, and You're Getting Paged at 3AM
GitHub Actions Marketplace - Where CI/CD Actually Gets Easier
integrates with GitHub Actions Marketplace
GitHub Actions Alternatives That Don't Suck
integrates with GitHub Actions
GitHub Actions + Docker + ECS: Stop SSH-ing Into Servers Like It's 2015
Deploy your app without losing your mind or your weekend
Jenkins + Docker + Kubernetes: How to Deploy Without Breaking Production (Usually)
The Real Guide to CI/CD That Actually Works
Jenkins Production Deployment - From Dev to Bulletproof
integrates with Jenkins
Jenkins - The CI/CD Server That Won't Die
integrates with Jenkins
Why I Finally Dumped Cassandra After 5 Years of 3AM Hell
integrates with MongoDB
Docker Swarm Node Down? Here's How to Fix It
When your production cluster dies at 3am and management is asking questions
Docker Swarm Service Discovery Broken? Here's How to Unfuck It
When your containers can't find each other and everything goes to shit
Docker Swarm - Container Orchestration That Actually Works
Multi-host Docker without the Kubernetes PhD requirement
containerd - The Container Runtime That Actually Just Works
The boring container runtime that Kubernetes uses instead of Docker (and you probably don't need to care about it)
VS Code Settings Are Probably Fucked - Here's How to Fix Them
Same codebase, 12 different formatting styles. Time to unfuck it.
Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization