# AWOOOI - Local Development Environment # ======================================= # Phase 7: 容器化聯合測試環境 # # Usage: # docker compose up -d # 啟動所有服務 # docker compose logs -f api # 查看 API 日誌 # docker compose down -v # 停止並清除資料 # # Services: # - web: Next.js 前端 (port 3000) # - api: FastAPI 後端 (port 8000) # - postgres: PostgreSQL 資料庫 (port 5432) # - redis: Redis 快取 (port 6379) services: # ========================================================================== # PostgreSQL Database # ========================================================================== postgres: image: postgres:16-alpine container_name: awoooi-postgres restart: unless-stopped environment: POSTGRES_USER: awoooi POSTGRES_PASSWORD: awoooi_dev_2026 POSTGRES_DB: awoooi_dev volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U awoooi -d awoooi_dev"] interval: 10s timeout: 5s retries: 5 # ========================================================================== # Redis Cache # ========================================================================== redis: image: redis:7-alpine container_name: awoooi-redis restart: unless-stopped ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 # ========================================================================== # FastAPI Backend # ========================================================================== api: build: context: ./apps/api dockerfile: Dockerfile container_name: awoooi-api restart: unless-stopped ports: - "8000:8000" environment: ENVIRONMENT: dev DEBUG: "true" LOG_LEVEL: INFO MOCK_MODE: "true" # Database (統帥鐵律: 禁止 SQLite, PostgreSQL ONLY) DATABASE_URL: postgresql+asyncpg://awoooi:awoooi_dev_2026@postgres:5432/awoooi_dev # Redis REDIS_URL: redis://redis:6379/0 # CORS (容器內使用 service name + localhost 開發端口) CORS_ORIGINS: '["http://localhost:3000","http://localhost:3001","http://localhost:3002","http://localhost:3003","http://web:3000"]' # Telegram Gateway (Phase 5.5) OPENCLAW_TG_BOT_TOKEN: "8569720657:AAHdvKf_P2ms-QKFTyqTLtLiqEggz8cpjMk" OPENCLAW_TG_CHAT_ID: "5619078117" OPENCLAW_TG_USER_WHITELIST: "5619078117" # External Services (使用 host.docker.internal 存取宿主機服務) OLLAMA_URL: http://host.docker.internal:11434 CLAWBOT_URL: http://host.docker.internal:8089 depends_on: postgres: condition: service_healthy redis: condition: service_healthy volumes: # 開發時掛載程式碼以支援熱重載 - ./apps/api/src:/app/src:ro # K8s kubeconfig for ActionExecutor (Phase 3) - ./apps/api/k3s-prod.yaml:/app/k3s-prod.yaml:ro healthcheck: test: ["CMD", "python", "-c", "import httpx; httpx.get('http://localhost:8000/api/v1/health', timeout=5)"] interval: 30s timeout: 10s start_period: 10s retries: 3 # ========================================================================== # Next.js Frontend # ========================================================================== web: build: context: . dockerfile: apps/web/Dockerfile args: # Build-time arg: NEXT_PUBLIC_* 需在打包時注入 NEXT_PUBLIC_API_URL: http://localhost:8000 container_name: awoooi-web restart: unless-stopped ports: - "3000:3000" environment: NODE_ENV: production # API URL - Browser 需使用 localhost (Docker 對外暴露的 port) # 注意: NEXT_PUBLIC_* 是給瀏覽器用的,非 Docker 內部網路 NEXT_PUBLIC_API_URL: http://localhost:8000 depends_on: api: condition: service_healthy healthcheck: # 使用 node 而非 wget,因為 Alpine 精簡鏡像 wget 有相容性問題 test: ["CMD", "node", "-e", "require('http').get('http://127.0.0.1:3000/', (r) => process.exit(r.statusCode === 200 || r.statusCode === 307 ? 0 : 1)).on('error', () => process.exit(1))"] interval: 30s timeout: 10s start_period: 30s retries: 3 volumes: postgres_data: redis_data: networks: default: name: awoooi-network