# XXX 威联通/QNAP NAS 部署模板。 # XXX 使用前建议复制一份 .env,按实际 NAS IP、域名、代理和密钥修改变量。 services: tuwen_db: image: postgres:16-alpine container_name: tuwen_db restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-surclaw} POSTGRES_USER: ${POSTGRES_USER:-surclaw} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-surclaw_dev_password} volumes: # XXX 默认适配威联通 Container 共享目录;如目录不同,修改 NAS_DATA_ROOT。 - ${NAS_DATA_ROOT:-/share/Container/tuwen_system_v2/data}/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER:-surclaw} -d $${POSTGRES_DB:-surclaw}"] interval: 10s timeout: 5s retries: 10 tuwen_api: build: # XXX 威联通 Container Station 对绝对路径解析不稳定,保持相对 context。 context: . dockerfile: Dockerfile.server args: HTTP_PROXY: ${HTTP_PROXY:-} HTTPS_PROXY: ${HTTPS_PROXY:-} NO_PROXY: ${NO_PROXY:-localhost,127.0.0.1,tuwen_db,tuwen_api,tuwen_web,api,db,web} container_name: tuwen_api restart: unless-stopped networks: default: aliases: # XXX nginx.conf 中 /api 固定代理到 http://api:3100,NAS 服务需要保留该别名。 - api depends_on: tuwen_db: condition: service_healthy ports: # XXX API 诊断端口;公网访问应走 web:4002/Nginx Proxy Manager。 - "${NAS_API_PORT:-4102}:3100" volumes: # XXX 持久化签名、视频、关键帧和模板图片等上传文件。 - ${NAS_DATA_ROOT:-/share/Container/tuwen_system_v2/data}/uploads:/app/uploads environment: NODE_ENV: production API_PORT: 3100 API_BODY_LIMIT: ${API_BODY_LIMIT:-100mb} DATABASE_URL: postgresql://${POSTGRES_USER:-surclaw}:${POSTGRES_PASSWORD:-surclaw_dev_password}@tuwen_db:5432/${POSTGRES_DB:-surclaw}?schema=public # XXX 示例:CORS_ORIGIN=http://NAS_IP:4002,https://your-domain.example CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost:4002,https://localhost:4443} # XXX 生产环境必须替换;公网 HTTPS 入口建议同时设置 SESSION_COOKIE_SECURE=true 和 TRUST_PROXY=true。 SESSION_SECRET: ${SESSION_SECRET:-change-me-in-production} SESSION_COOKIE_SECURE: ${SESSION_COOKIE_SECURE:-false} TRUST_PROXY: ${TRUST_PROXY:-false} FILE_STORAGE_DIR: /app/uploads RUN_DB_MIGRATIONS: ${RUN_DB_MIGRATIONS:-true} RUN_DB_SEED: ${RUN_DB_SEED:-true} DOCKER_STARTUP_RETRIES: ${DOCKER_STARTUP_RETRIES:-30} DOCKER_STARTUP_RETRY_DELAY: ${DOCKER_STARTUP_RETRY_DELAY:-2} HTTP_PROXY: ${HTTP_PROXY:-} HTTPS_PROXY: ${HTTPS_PROXY:-} http_proxy: ${HTTP_PROXY:-} https_proxy: ${HTTPS_PROXY:-} NO_PROXY: ${NO_PROXY:-localhost,127.0.0.1,tuwen_db,tuwen_api,tuwen_web,api,db,web} healthcheck: # XXX 使用 127.0.0.1,规避部分 NAS 固件中 localhost 优先解析 IPv6 的问题。 test: ["CMD-SHELL", "node -e \"fetch('http://127.0.0.1:3100/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""] interval: 10s timeout: 5s retries: 12 start_period: 20s tuwen_web: build: context: . dockerfile: Dockerfile args: HTTP_PROXY: ${HTTP_PROXY:-} HTTPS_PROXY: ${HTTPS_PROXY:-} NO_PROXY: ${NO_PROXY:-localhost,127.0.0.1,tuwen_db,tuwen_api,tuwen_web,api,db,web} container_name: tuwen_web restart: unless-stopped depends_on: tuwen_api: condition: service_healthy ports: - "${NAS_WEB_PORT:-4002}:80" # XXX 仅用于本机自签名 HTTPS 演示;公网 HTTPS 应由 Nginx Proxy Manager 提供。 - "${NAS_HTTPS_DEMO_PORT:-4443}:443" environment: APP_URL: ${APP_URL:-http://localhost:4002} healthcheck: test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1/ || exit 1"] interval: 10s timeout: 5s retries: 6 tuwen_frpc: # XXX 威联通 Container Station 通常不会启用 Compose profiles,所以 NAS 版默认启动 frpc。 # XXX 启用前先编辑 frpc/frpc.nas.toml;如果不需要公网映射,可删除/注释整个 tuwen_frpc 服务。 image: snowdreamtech/frpc:latest container_name: tuwen_frpc restart: unless-stopped command: ["frpc", "-c", "/etc/frp/frpc.toml"] volumes: - ./frpc/frpc.nas.toml:/etc/frp/frpc.toml:ro depends_on: tuwen_web: condition: service_healthy