10. Docker Compose Deployment
Docker Compose orchestrates multi-container deployments for development and staging. Production typically uses Kubernetes, but Docker Compose provides a simpler path for smaller deployments. The compose file defines services, networks, volumes, and dependencies.
# docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: aiapp
POSTGRES_USER: aiapp
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
volumes:
- postgres_data:/var/lib/postgresql/data
secrets:
- postgres_password
healthcheck:
test: ["CMD-SHELL", "pg_isready -U aiapp"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
backend:
build:
context: ./backend
dockerfile: Dockerfile
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
model_server:
condition: service_healthy
environment:
DATABASE_URL: postgresql://aiapp@postgres/aiapp
REDIS_URL: redis://redis:6379
MODEL_SERVER_URL: http://model_server:8080
SECRET_KEY_FILE: /run/secrets/secret_key
secrets:
- postgres_password
- secret_key
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 512M
model_server:
build:
context: ./model-server
dockerfile: Dockerfile
environment:
MODEL_PATH: /models/mistral-7b.q4_k_m.gguf
CONTEXT_SIZE: 4096
volumes:
- model_cache:/models
deploy:
resources:
limits:
memory: 8G
reservations:
devices:
- capabilities: [gpu]
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
depends_on:
- backend
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/certs:/etc/nginx/certs:ro
depends_on:
- backend
- frontend
volumes:
postgres_data:
redis_data:
model_cache:
secrets:
postgres_password:
file: ./secrets/postgres_password.txt
secret_key:
file: ./secrets/secret_key.txt
Resource limits prevent any service from consuming all host memory. The memory reservation tells Docker to pre-allocate memory for the container, improving performance. The GPU reservation requires the Docker runtime to have GPU access configured.
Secrets management requires secure file permissions. Secrets files should have 0600 permissions:
# Create secrets directory with restricted access
mkdir -p secrets
chmod 700 secrets
echo "your-secure-password" > secrets/postgres_password.txt
chmod 600 secrets/postgres_password.txt
Common Docker Compose failures include port conflicts when services try to bind to ports already in use. Check with netstat -tulpn | grep LISTEN. Volume permission issues when UIDs mismatch between host and container—use named volumes instead of bind mounts to avoid this.
Create a Docker Compose file that starts the full stack with health checks and resource limits. Verify all services start successfully and communicate.