⚠️ Note: This is the detailed reference documentation. For quick start instructions, see DOCKER-QUICKSTART.md
Last Updated: October 12, 2025
Status: ✅ Complete and operational
This project uses Docker and Docker Compose for containerized deployment with multi-stage builds for optimized production images.
┌─────────────────────────────────────────────────────────┐
│ Nginx (Port 80) │
│ Reverse Proxy │
└──────┬─────────────────────────────────────┬────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ Frontend │ │ Backend │
│ (React) │ │ (Django) │
│ Port 80 │ │ Port 8000 │
└──────────────┘ └────────┬─────────┘
│
┌──────────┼──────────┐
│ │ │
┌───────▼──┐ ┌───▼────┐ ┌──▼──────┐
│PostgreSQL│ │ Redis │ │ Celery │
│ Port │ │ Port │ │ Worker │
│ 5432 │ │ 6379 │ │ │
└──────────┘ └────────┘ └─────────┘
- Docker 20.10+
- Docker Compose 2.0+
- 4GB RAM minimum
- 10GB disk space
# 1. Copy environment file
cp .env.example .env
# 2. Edit .env and add your GROQ_API_KEY
nano .env
# 3. Start development environment
./scripts/docker-dev.sh
# Or manually:
docker-compose -f docker-compose.dev.yml up -d
# 4. Run migrations
docker-compose -f docker-compose.dev.yml exec backend python manage.py migrate
# 5. Create superuser
docker-compose -f docker-compose.dev.yml exec backend python manage.py createsuperuserAccess Points:
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000/api/
- Django Admin: http://localhost:8000/admin/
# 1. Copy and configure environment
cp .env.example .env
# 2. Edit .env with production values
# IMPORTANT: Change all passwords and SECRET_KEY!
nano .env
# 3. Start production environment
./scripts/docker-start.sh
# Or manually:
docker-compose up -d
# 4. Check health
docker-compose ps
curl http://localhost/api/health/Access Points:
- Application: http://localhost
- API: http://localhost/api/
- Django Admin: http://localhost/admin/
Production Build:
- Base:
python:3.11-slim - Multi-stage build
- Size: ~450MB (optimized)
- Features:
- Non-root user for security
- Health checks
- Gunicorn with 4 workers
- FFmpeg for audio processing
- PostgreSQL client
Development Build:
- Base:
python:3.11-slim - Includes debug tools (ipython, pytest)
- Hot reload enabled
- Django development server
Production Build:
- Stage 1:
node:18-alpine(builder) - Stage 2:
nginx:alpine(runtime) - Size: ~25MB (highly optimized)
- Features:
- Optimized production build
- Nginx with compression
- Security headers
- Health check endpoint
Development Build:
- Base:
node:18-alpine - Hot reload enabled
- React development server on port 3000
# Django
SECRET_KEY=your-strong-secret-key-here
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
# Database
DB_NAME=hardword
DB_USER=hardword
DB_PASSWORD=strong-password-here
# Redis
REDIS_PASSWORD=strong-password-here
# API Keys
GROQ_API_KEY=your-groq-api-key-here
# Admin
ADMIN_PASSWORD=strong-admin-password-here# Whisper
WHISPER_MODEL=base # Options: tiny, base, small, medium, large
# File Upload
MAX_UPLOAD_SIZE=104857600 # 100MB
# CORS
CORS_ALLOWED_ORIGINS=https://yourdomain.com-
db - PostgreSQL 15
- Persistent volume:
postgres_data - Health checks enabled
- Auto-restart
- Persistent volume:
-
redis - Redis 7
- Persistent volume:
redis_data - Password protected
- AOF persistence enabled
- Persistent volume:
-
backend - Django Application
- Depends on: db, redis
- Gunicorn with 4 workers
- Health checks via
/api/health/ - Volumes: media, staticfiles, logs
-
celery - Celery Worker
- Depends on: backend, redis
- 4 concurrent workers
- Health checks via Celery inspect
-
frontend - React Application
- Depends on: backend
- Nginx serves static files
- Optimized production build
-
nginx - Reverse Proxy
- Depends on: backend, frontend
- Routes
/api/to backend - Routes
/to frontend - Serves static/media files
- Compression enabled
- Hot reload enabled for backend and frontend
- Source code mounted as volumes
- Django development server
- React development server (port 3000)
- Debug tools included
- Simplified configuration
# List volumes
docker volume ls | grep hardword
# Backup volumes
docker run --rm \
-v hardword_postgres_data:/data \
-v $(pwd)/backup:/backup \
alpine tar czf /backup/postgres-backup.tar.gz /data
# Restore volume
docker run --rm \
-v hardword_postgres_data:/data \
-v $(pwd)/backup:/backup \
alpine tar xzf /backup/postgres-backup.tar.gz -C /
# Remove volumes (DANGER: Data loss!)
docker-compose down -vAll services include health checks:
# Check all services
docker-compose ps
# Check backend health
curl http://localhost/api/health/
# View health check logs
docker inspect --format='{{json .State.Health}}' hardword_backend | jq
# Manual health checks
docker-compose exec db pg_isready -U hardword
docker-compose exec redis redis-cli ping
docker-compose exec celery celery -A config inspect ping# View all logs
docker-compose logs -f
# View specific service
docker-compose logs -f backend
docker-compose logs -f celery
# Last 100 lines
docker-compose logs --tail=100 backend
# Export logs
docker-compose logs --no-color > logs/docker-$(date +%Y%m%d).log# Start (production)
docker-compose up -d
# Start (development)
docker-compose -f docker-compose.dev.yml up -d
# Stop
docker-compose down
# Stop and remove volumes
docker-compose down -v# Run migrations
docker-compose exec backend python manage.py migrate
# Create superuser
docker-compose exec backend python manage.py createsuperuser
# Database shell
docker-compose exec backend python manage.py dbshell
# Backup database
docker-compose exec db pg_dump -U hardword hardword > backup.sql
# Restore database
docker-compose exec -T db psql -U hardword hardword < backup.sql# Rebuild images
docker-compose build --no-cache
# Update images
docker-compose pull
# Clean up
docker system prune -a
docker volume prune
# Shell access
docker-compose exec backend bash
docker-compose exec frontend sh# Check logs
docker-compose logs service_name
# Check health
docker-compose ps
# Restart service
docker-compose restart service_name# Check PostgreSQL is running
docker-compose exec db pg_isready -U hardword
# Check connection from backend
docker-compose exec backend python manage.py dbshell# Check Redis
docker-compose exec redis redis-cli ping
# Check with password
docker-compose exec redis redis-cli -a your-password ping# Check Celery is running
docker-compose exec celery celery -A config inspect ping
# Check active tasks
docker-compose exec celery celery -A config inspect active
# Restart Celery
docker-compose restart celery# Fix media/static permissions
docker-compose exec backend chown -R django:django /app/media /app/staticfiles- Change default passwords in
.env - Use strong SECRET_KEY (50+ random characters)
- Enable HTTPS in production (use Certbot/Let's Encrypt)
- Restrict ALLOWED_HOSTS to your domain
- Set DEBUG=False in production
- Regular backups of database and media files
- Update Docker images regularly
- Monitor logs for suspicious activity
- Use Docker secrets for sensitive data (advanced)
- Limit container resources (CPU/memory)
# Calculate workers: (2 x CPU cores) + 1
# Edit docker-compose.yml:
command: gunicorn ... --workers 8 # For 4-core server# Adjust based on workload
command: celery -A config worker --concurrency=8# Increase shared_buffers (in db service)
command: postgres -c shared_buffers=256MB -c max_connections=200Add to docker/nginx-proxy.conf:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=1g;
location /api/ {
proxy_cache api_cache;
proxy_cache_valid 200 5m;
...
}# Add to docker-compose.yml
prometheus:
image: prom/prometheus
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3001:3000"
volumes:
- grafana_data:/var/lib/grafana# Monitor resources
docker stats
# View container resource limits
docker inspect hardword_backend | grep -A 10 "Resources"name: Docker Build
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker images
run: docker-compose build
- name: Run tests
run: |
docker-compose run backend python manage.py test
docker-compose run frontend npm test
- name: Push to registry
run: |
docker-compose push- Environment variables configured
- Strong passwords set
- DEBUG=False
- ALLOWED_HOSTS configured
- Database backed up
- SSL/HTTPS enabled
- Firewall configured
- Monitoring setup
- Log rotation enabled
- Backup strategy implemented
- Health checks verified
- Performance tested
- Security audit completed
For issues:
- Check logs:
docker-compose logs - Verify health:
docker-compose ps - Review configuration:
.envfile - Consult docs/TROUBLESHOOTING.md
- Open GitHub issue with logs and configuration (sanitized)
MIT License - See LICENSE file for details