services: db: image: postgres:17 environment: POSTGRES_USER: ${POSTGRES_USER:-campusclaw} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?请设置 POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB:-campusclaw} POSTGRES_INITDB_ARGS: --encoding=UTF8 --locale=C volumes: - campusclaw-postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""] interval: 5s timeout: 3s retries: 12 restart: unless-stopped backend: build: ./backend environment: # 部署时必须覆盖:开发默认密钥不适用于生产 CAMPUSCLAW_JWT_SECRET: ${CAMPUSCLAW_JWT_SECRET:-change-me-in-deployment} CAMPUSCLAW_DATABASE_URL: ${CAMPUSCLAW_DATABASE_URL:?请设置 CAMPUSCLAW_DATABASE_URL} depends_on: db: condition: service_healthy healthcheck: test: ["CMD", "python", "-c", "import urllib.request;urllib.request.urlopen('http://127.0.0.1:8000/health')"] interval: 5s timeout: 3s retries: 12 restart: unless-stopped frontend: build: context: ./frontend args: # 浏览器只访问前端同源的 /api,由 Next.js rewrites 反代到后端服务名。 # rewrites 固化在构建产物里,因此这里是 build arg 而非运行期环境变量。 API_PROXY_TARGET: http://backend:8000 ports: - "3000:3000" depends_on: backend: condition: service_healthy restart: unless-stopped volumes: campusclaw-postgres: