version: '3.9' services: backend: build: context: ./backend dockerfile: Dockerfile.prod restart: unless-stopped ports: - "8000:8000" volumes: - ./data/gpx:/app/data/gpx - ./data/sessions:/app/data/sessions - ./data/logs:/app/logs logging: driver: "json-file" options: max-size: "10m" max-file: "5" environment: - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/cycling - API_KEY=${API_KEY} - GARMIN_USERNAME=${GARMIN_USERNAME} - GARMIN_PASSWORD=${GARMIN_PASSWORD} - OPENROUTER_API_KEY=${OPENROUTER_API_KEY} - AI_MODEL=${AI_MODEL} depends_on: db: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 frontend: build: context: ./frontend dockerfile: Dockerfile restart: unless-stopped ports: - "80:80" environment: - REACT_APP_API_URL=http://backend:8000 - NODE_ENV=production healthcheck: test: ["CMD", "curl", "-f", "http://localhost:80/healthz"] interval: 30s timeout: 10s retries: 3 depends_on: backend: condition: service_healthy deploy: resources: limits: memory: 512M cpus: '0.5' db: image: postgres:15-alpine restart: unless-stopped volumes: - postgres_data:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s timeout: 5s retries: 5 volumes: postgres_data: