services: db: image: postgres:16-alpine environment: POSTGRES_USER: ${POSTGRES_USER:-langlearn} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB:-langlearn} volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-langlearn}"] interval: 5s timeout: 5s retries: 10 storage: image: minio/minio:latest command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${STORAGE_ACCESS_KEY:-langlearn} MINIO_ROOT_PASSWORD: ${STORAGE_SECRET_KEY} ports: - "9000:9000" - "9001:9001" volumes: - storagedata:/data healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:9000/minio/health/live || exit 1"] interval: 5s timeout: 5s retries: 10 api: build: ./api ports: - "${API_PORT:-8000}:8000" environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-langlearn}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-langlearn} JWT_SECRET: ${JWT_SECRET} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} DEEPL_API_KEY: ${DEEPL_API_KEY} DEEPGRAM_API_KEY: ${DEEPGRAM_API_KEY} GEMINI_API_KEY: ${GEMINI_API_KEY} STORAGE_ENDPOINT_URL: http://storage:9000 STORAGE_ACCESS_KEY: ${STORAGE_ACCESS_KEY:-langlearn} STORAGE_SECRET_KEY: ${STORAGE_SECRET_KEY} STORAGE_BUCKET: ${STORAGE_BUCKET:-langlearn} depends_on: db: condition: service_healthy storage: condition: service_healthy restart: unless-stopped frontend: build: context: ./frontend args: PUBLIC_API_BASE_URL: ${PUBLIC_API_BASE_URL:-http://localhost:8000} ports: - "${FRONTEND_PORT:-3000}:3000" environment: ORIGIN: ${ORIGIN:-http://localhost:3000} depends_on: - api restart: unless-stopped volumes: pgdata: storagedata: