# docker-compose.yml — HALE Production Stack services: # ── HALE API ────────────────────────────────────────────────── api: build: . ports: - "8000:8000" env_file: - .env volumes: - ./data:/app/data - ./logs:/app/logs depends_on: db: condition: service_healthy redis: condition: service_healthy environment: - DATABASE_URL=postgresql://hale:hale_secret@db:5432/hale - REDIS_URL=redis://redis:6379/0 restart: unless-stopped deploy: resources: limits: memory: 512M cpus: "0.5" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 start_period: 20s # ── PostgreSQL ─────────────────────────────────────────────── db: image: postgres:16-alpine environment: POSTGRES_DB: hale POSTGRES_USER: hale POSTGRES_PASSWORD: hale_secret ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data restart: unless-stopped deploy: resources: limits: memory: 256M cpus: "0.5" healthcheck: test: ["CMD-SHELL", "pg_isready -U hale -d hale"] interval: 10s timeout: 5s retries: 5 start_period: 10s # ── Redis (rate limiting + lesson cache in prod) ───────────── redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redisdata:/data restart: unless-stopped command: redis-server --maxmemory 64mb --maxmemory-policy allkeys-lru deploy: resources: limits: memory: 80M cpus: "0.1" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 3 volumes: pgdata: redisdata: