Docker Development Setup
📚 Part of: Docker Guide - Return to Docker overview
Complete guide for running Django-CFG in local development with Docker Compose.
Quick Start
# Navigate to docker directory
cd docker
# Start all services
docker compose up -d
# Check status
docker compose ps
# View logs
docker compose logs -fAll services should be healthy in ~60 seconds.
Project Structure
docker/
├── docker-compose.yaml # Main compose file
├── .env # Environment variables
├── .dockerignore # Build context exclusions
│
├── services/ # Service-specific configs
│ ├── django/
│ │ ├── Dockerfile # Django application
│ │ ├── entrypoint.sh # Container startup
│ │ ├── config.dev.ignore.yaml # Dev API keys (in git!)
│ │ └── config.prod.ignore.yaml# Prod API keys (in git!)
│ ├── demo/Dockerfile # Next.js demo app
│ ├── websocket/Dockerfile # WebSocket RPC server
│ ├── web/Dockerfile # Nuxt.js docs site
│ └── postgres/init.sql # DB initialization
│
├── volumes/ # Persistent data (git-ignored)
│ ├── postgres/ # Database files
│ ├── django/media/ # User uploads
│ └── django/logs/ # Application logs
│
└── @docs/ # Documentation
├── README.md # Complete reference
├── CONFIG_STRATEGY.md # Configuration guide
├── DOCKER_BUILD_LESSONS.md # Build optimization
└── QUICK_REFERENCE.md # Command referenceService Configuration
Infrastructure Services
PostgreSQL Database
Port: 5432 (internal)
Databases: djangocfg (main)
Extensions: uuid-ossp, pg_trgm, vector (pgvector)
postgres:
image: pgvector/pgvector:pg15
environment:
POSTGRES_DB: djangocfg
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d djangocfg"]
interval: 10sEnvironment variable:
DATABASE_URL=postgresql://postgres:password@postgres:5432/djangocfgRedis Cache & Queue
Port: 6379 (internal)
Databases:
- DB 0: Django cache
- DB 1: ReArq task queue
- DB 2: Centrifugo broker
redis:
image: redis:7-alpine
command: >
redis-server
--maxmemory 512mb
--maxmemory-policy allkeys-lru
--databases 3Environment variables:
REDIS_URL=redis://redis:6379/0
REDIS_REARQ_URL=redis://redis:6379/1Backend Services
Django API
Port: 8300:8000
Access: http://localhost:8300
django:
build:
context: ..
dockerfile: docker/services/django/Dockerfile
environment:
DJANGO_SETTINGS_MODULE: api.settings
DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/djangocfg
REDIS_URL: redis://redis:6379/0
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/cfg/health/"]
interval: 30sKey features:
- Auto-runs migrations on startup
- Health check endpoint at
/cfg/health/ - Volume-mounted media files
- Hot-reload enabled
Django ReArq Workers
Container: django-rearq
Purpose: Background task processing
django-rearq:
image: djangocfg-django:latest
environment:
SKIP_MIGRATIONS: "true"
REARQ_WORKERS: 2
command: ["/entrypoint.sh", "rearq", "main:rearq", "worker"]
depends_on:
django:
condition: service_healthyConfiguration:
REARQ_WORKERS: Number of worker processes (default: 2)- Skips migrations (handled by main Django service)
WebSocket RPC Server
Ports:
9065: WebSocket connections9066: Health check
Access: ws://localhost:9065
websocket:
environment:
WS_HOST: 0.0.0.0
WS_PORT: 9065
HEALTH_PORT: 9066
REDIS_URL: redis://redis:6379/2
JWT_SECRET: ${JWT_SECRET}Frontend Services
Demo Application (Next.js)
Port: 3300
Access: http://localhost:3300
Built with Next.js standalone output for minimal image size.
Documentation Site (Nuxt.js)
Port: 3301
Access: http://localhost:3301
This documentation site you’re reading now!
Traefik Reverse Proxy
Dashboard: http://localhost:8390
HTTP: Port 380
HTTPS: Port 743
Routes:
api.localhost:380→ Django APIdemo.localhost:380→ Demo appws.localhost:380→ WebSocket
Access via Traefik For a production-like experience, access services through Traefik:
http://api.localhost:380/admin/
http://demo.localhost:380Common Development Tasks
Django Management
# Run migrations
docker exec django python manage.py migrate
# Create superuser
docker exec -it django python manage.py createsuperuser
# Django shell
docker exec -it django python manage.py shell
# Collect static files (if needed)
docker exec django python manage.py collectstatic --noinput
# Custom management command
docker exec django python manage.py your_commandDatabase Operations
# Access PostgreSQL shell
docker exec -it djangocfg_postgres psql -U postgres -d djangocfg
# Run SQL query
docker exec djangocfg_postgres psql -U postgres -d djangocfg -c "SELECT * FROM django_migrations LIMIT 5;"
# Backup database
docker exec djangocfg_postgres pg_dump -U postgres djangocfg > backup.sql
# Restore database
docker exec -i djangocfg_postgres psql -U postgres djangocfg < backup.sql
# Reset database (⚠️ DESTRUCTIVE)
docker exec djangocfg_postgres psql -U postgres -c "DROP DATABASE djangocfg;"
docker exec djangocfg_postgres psql -U postgres -c "CREATE DATABASE djangocfg;"
docker exec django python manage.py migrateView Logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f django
# Last 50 lines
docker compose logs --tail=50 django
# With timestamps
docker compose logs -f --timestamps djangoService Management
# Restart single service
docker compose restart django
# Stop all services
docker compose stop
# Start all services
docker compose start
# Remove all services (keeps volumes)
docker compose down
# Remove all including volumes (⚠️ DELETES DATA)
docker compose down -vRebuild After Changes
# Rebuild single service
docker compose build django --no-cache
docker compose up -d django
# Rebuild all services
docker compose build --no-cache
docker compose up -d
# Force recreate containers
docker compose up -d --force-recreateConfiguration
Environment Variables
Edit docker/.env:
# Database
POSTGRES_DB=djangocfg
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_password_here
# Django
DJANGO_SECRET_KEY=your-secret-key-here
DJANGO_DEBUG=true
# ReArq
REARQ_WORKERS=2
# API Keys (optional)
ANTHROPIC_API_KEY=sk-ant-your-key
OPENAI_API_KEY=sk-proj-your-key
# JWT
JWT_SECRET_KEY=your-jwt-secret-hereYAML Configuration Files
Django-CFG uses YAML files for detailed configuration:
For Docker development (team-shared API keys):
# docker/services/django/config.dev.ignore.yaml
api_keys:
openai: "sk-proj-your-team-key"
anthropic: "sk-ant-your-team-key"
email:
backend: "smtp"
host: "mail.example.com"
username: "[email protected]"
password: "smtp-password"Why .ignore.yaml in Git? Docker configs with team-shared API keys are intentionally committed:
docker/services/django/*.ignore.yaml- Team configs (in git)projects/django/api/environment/*.ignore.yaml- Personal (git-ignored)
See Configuration Strategy for details.
Service Access
| Service | URL | Credentials |
|---|---|---|
| Django Admin | http://localhost:8300/admin/ | Create with createsuperuser |
| Django API | http://localhost:8300 | - |
| API via Traefik | http://api.localhost:380 | - |
| Demo App | http://localhost:3300 | - |
| Demo via Traefik | http://demo.localhost:380 | - |
| Documentation | http://localhost:3301 | - |
| Traefik Dashboard | http://localhost:8390 | - |
| PostgreSQL | localhost:5432 | postgres / (from .env) |
| Redis | localhost:6379 | No password |
Troubleshooting
Services Won’t Start
Check logs:
docker compose logs django
docker compose psCommon issues:
- Ports already in use → Change ports in docker-compose.yaml
- Previous containers running →
docker compose down - Build cache issues →
docker compose build --no-cache
Configuration Not Loading
Check which config is loaded:
docker exec django python -c "from api.environment.loader import env; print(env.env.env_mode)"
# Should output: developmentVerify config file exists:
docker exec django ls -la /app/api/environment/Database Connection Failed
Check database is healthy:
docker compose ps djangocfg_postgres
docker exec djangocfg_postgres pg_isready -U postgresTest connection:
docker exec django python manage.py check --database defaultPort Already in Use
Find process using port:
lsof -i :8300Kill process:
kill -9 <PID>Or change port in docker-compose.yaml:
ports:
- "8301:8000" # Changed from 8300Volume Permission Errors
Fix permissions:
sudo chown -R $USER:$USER docker/volumes/Performance Tips
Optimize Build Speed
- Use .dockerignore - Already configured
- Layer caching - Don’t change Dockerfile often
- BuildKit - Enable with
DOCKER_BUILDKIT=1
Reduce Container Size
Images are optimized with multi-stage builds:
- Django: ~300MB
- Next.js demo: ~300MB (with standalone output)
- Nuxt.js docs: ~200MB
See Build Optimization for details.
Improve Runtime Performance
# Increase workers
REARQ_WORKERS=4
# Increase Redis memory
redis:
command: redis-server --maxmemory 1gbNext Steps
Production Deployment: Production Docker Setup →
Configuration Deep Dive: Configuration Strategy →
Build Optimization: Build Optimization Guide →
Common Issues: Troubleshooting Guide →
See Also
Docker Guides
- Docker Overview - Complete Docker guide
- Production Setup - Deploy to production
- Configuration - YAML + env vars strategy
- Build Optimization - Performance tips
- Troubleshooting - Quick fixes
Configuration
- Database Configuration - PostgreSQL setup
- Cache Configuration - Redis setup
- Environment Variables - Env vars
Getting Started
- First Project - Create your first app
- Installation - Install Django-CFG
- Configuration Guide - Basic setup
TAGS: docker, development, docker-compose, local-setup DEPENDS_ON: [docker, docker-compose, postgresql, redis] USED_BY: [development, testing, local-environment]