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 healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-langlearn}"] interval: 10s timeout: 5s retries: 10 restart: unless-stopped deploy: resources: limits: cpus: '1' memory: 1G api: build: ./api ports: - "${API_PORT:-8000}:8000" command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 2 environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-langlearn}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-langlearn} ADMIN_USER_EMAILS: ${ADMIN_USER_EMAILS} API_BASE_URL: ${API_BASE_URL} 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} PYTHONPATH: /app STORAGE_PROVIDER: bunny BUNNY_ZONE: ${BUNNY_ZONE} BUNNY_API_KEY: ${BUNNY_API_KEY} BUNNY_CDN_BASE_URL: ${BUNNY_CDN_BASE_URL} BUNNY_TOKEN_AUTH_KEY: ${BUNNY_TOKEN_AUTH_KEY} TRANSACTIONAL_EMAIL_PROVIDER: ${TRANSACTIONAL_EMAIL_PROVIDER} healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8000/health || exit 1"] interval: 10s timeout: 5s retries: 10 start_period: 20s depends_on: db: condition: service_healthy restart: unless-stopped deploy: resources: limits: cpus: '1' memory: 1G frontend: build: context: ./frontend args: PUBLIC_API_BASE_URL: ${PUBLIC_API_BASE_URL} ports: - "${FRONTEND_PORT:-3000}:3000" environment: ORIGIN: ${ORIGIN} depends_on: api: condition: service_healthy restart: unless-stopped deploy: resources: limits: cpus: '0.5' memory: 256M volumes: pgdata: networks: default: name: langlearn