diff --git a/README.md b/README.md index 2addca4..39a342b 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,55 @@ docker-compose down - `nginx.conf` 已支持 `/api/speech/iat` WebSocket upgrade。 完整 Docker 说明见 [docs/docker.md](./docs/docker.md)。 +## 威联通 NAS 部署 + + + +仓库提供 [docker-compose-Nas.yaml](./docker-compose-Nas.yaml),用于在威联通 NAS 上直接部署完整图文报告系统。它与默认 Compose 的主要区别: + +- 使用 `/share/Container/tuwen_system_v2/data` 作为默认持久化目录。`# XXX` 如 NAS 共享目录不同,修改 `NAS_DATA_ROOT` 或 compose 文件中的路径。 +- API 默认映射到 NAS 宿主机 `4102`,前端仍映射到 `4002`。 +- 保留 `api` 网络别名,确保容器内 Nginx 可以继续把 `/api` 代理到后端。 +- 使用 `127.0.0.1` 做 API 健康检查,规避部分 NAS 固件上的 IPv6 localhost 解析问题。 +- 内置可选 `frpc` profile,可复用 [frpc/frpc.toml](./frpc/frpc.toml) 把 `4002` 映射到公网服务器。 + +NAS 终端部署: + +```bash +# XXX 进入 NAS 上的项目目录后执行。 +docker compose -f docker-compose-Nas.yaml up -d --build + +curl http://127.0.0.1:4002/api/health +docker compose -f docker-compose-Nas.yaml ps +``` + +公网部署时建议先准备 NAS `.env` 或 Container Station 环境变量: + +```bash +# XXX 必改:生产环境不要继续使用默认 Session 密钥。 +SESSION_SECRET=替换为足够长的随机字符串 + +# XXX 如果公网入口是 https://sstwbg.example.com,建议开启这两项。 +SESSION_COOKIE_SECURE=true +TRUST_PROXY=true +CORS_ORIGIN=http://192.168.31.5:4002,https://sstwbg.example.com + +# XXX 如需代理构建或让后端访问外网,可按 NAS 网络环境配置。 +HTTP_PROXY=http://192.168.31.7:7893 +HTTPS_PROXY=http://192.168.31.7:7893 +NO_PROXY=localhost,127.0.0.1,192.168.31.0/24,tuwen_db,tuwen_api,tuwen_web,api,db,web +``` + +启用 NAS 上的 frpc 隧道: + +```bash +# XXX 先编辑 frpc/frpc.toml,替换 serverAddr 和 auth.token。 +docker compose -f docker-compose-Nas.yaml --profile frpc up -d --build +docker compose -f docker-compose-Nas.yaml logs -f frpc +``` + +`# XXX` NAS 公网访问仍然只需要把 `4002` 通过 frpc 映射到公网服务器,再由 Nginx Proxy Manager 给 `sstwbg.example.com` 提供 HTTPS。`4443` 仍只是本机自签名 HTTPS 演示入口,不建议映射到公网域名。 + ## 公网反向代理部署 diff --git a/docker-compose-Nas.yaml b/docker-compose-Nas.yaml new file mode 100644 index 0000000..e9e35bf --- /dev/null +++ b/docker-compose-Nas.yaml @@ -0,0 +1,115 @@ +# XXX QNAP/NAS deployment compose. Designed for Container Station or docker compose on a NAS. +# XXX Edit /share paths, proxy variables, SESSION_SECRET, and frpc/frpc.toml before public deployment. + +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 NAS persistent database directory. Change this path if your QNAP share is different. + - ${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 Keep relative context for QNAP, otherwise Container Station may fail to resolve absolute paths. + context: . + dockerfile: Dockerfile.server + args: + HTTP_PROXY: ${HTTP_PROXY:-} + HTTPS_PROXY: ${HTTPS_PROXY:-} + NO_PROXY: ${NO_PROXY:-localhost,127.0.0.1,192.168.31.0/24,tuwen_db,tuwen_api,tuwen_web,api,db,web} + container_name: tuwen_api + restart: unless-stopped + networks: + default: + aliases: + # XXX nginx.conf proxies /api to http://api:3100, so NAS service keeps this alias. + - api + depends_on: + tuwen_db: + condition: service_healthy + ports: + # XXX Optional host API port for NAS diagnostics; public users should enter through web:4002/NPM. + - "${NAS_API_PORT:-4102}:3100" + volumes: + # XXX NAS persistent upload directory for signatures, videos, keyframes, and template images. + - ${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 + CORS_ORIGIN: ${CORS_ORIGIN:-http://192.168.31.5:4002,https://sstwbg.example.com} + # XXX Replace in NAS .env or Container Station variables before real deployment. + SESSION_SECRET: ${SESSION_SECRET:-change-me-in-production} + # XXX For public HTTPS through Nginx Proxy Manager, set SESSION_COOKIE_SECURE=true and TRUST_PROXY=true. + 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,192.168.31.0/24,tuwen_db,tuwen_api,tuwen_web,api,db,web} + healthcheck: + # XXX Use 127.0.0.1 instead of localhost to avoid IPv6 resolution issues on some NAS firmware. + 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: + # XXX Keep relative context for QNAP. + context: . + dockerfile: Dockerfile + args: + HTTP_PROXY: ${HTTP_PROXY:-} + HTTPS_PROXY: ${HTTPS_PROXY:-} + NO_PROXY: ${NO_PROXY:-localhost,127.0.0.1,192.168.31.0/24,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 Local self-signed HTTPS demo only. Public HTTPS should be handled by Nginx Proxy Manager. + - "${NAS_HTTPS_DEMO_PORT:-4443}:443" + environment: + APP_URL: ${APP_URL:-http://192.168.31.5:4002} + healthcheck: + test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1/ || exit 1"] + interval: 10s + timeout: 5s + retries: 6 + + frpc: + # XXX Optional public tunnel client. Edit frpc/frpc.toml before enabling this profile. + image: snowdreamtech/frpc:latest + container_name: tuwen_frpc + restart: unless-stopped + network_mode: host + command: ["-c", "/etc/frp/frpc.toml"] + volumes: + - ./frpc/frpc.toml:/etc/frp/frpc.toml:ro + depends_on: + tuwen_web: + condition: service_healthy + profiles: + - frpc diff --git a/docs/docker.md b/docs/docker.md index c7d3a02..9b05775 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -65,6 +65,39 @@ docker compose down docker compose down -v ``` +## 威联通 NAS 部署 + + + +NAS 部署可使用仓库内的 `docker-compose-Nas.yaml`: + +```bash +docker compose -f docker-compose-Nas.yaml up -d --build +curl http://127.0.0.1:4002/api/health +``` + +该配置默认把 PostgreSQL 和上传文件保存到 `/share/Container/tuwen_system_v2/data`,可通过 `NAS_DATA_ROOT` 覆盖。API 诊断端口默认为 `4102`,前端入口仍为 `4002`。 + +公网 HTTPS 部署时建议设置: + +```bash +# XXX 生产环境应替换 Session 密钥,并信任 Nginx Proxy Manager/frpc 链路传来的 HTTPS 协议头。 +SESSION_SECRET=替换为足够长的随机字符串 +SESSION_COOKIE_SECURE=true +TRUST_PROXY=true +CORS_ORIGIN=http://192.168.31.5:4002,https://sstwbg.example.com +``` + +启用 NAS 上的 frpc 隧道: + +```bash +# XXX 先编辑 frpc/frpc.toml,替换 serverAddr 和 auth.token。 +docker compose -f docker-compose-Nas.yaml --profile frpc up -d --build +docker compose -f docker-compose-Nas.yaml logs -f frpc +``` + +`# XXX` 公网正式入口只映射 `4002` 即可;不要把 `4443` 自签名 HTTPS 演示端口映射为公网域名入口。公网 HTTPS 应由 Nginx Proxy Manager 提供。 + ## 初始化开关 API 容器启动脚本为 `scripts/docker-api-entrypoint.sh`,可用环境变量控制初始化: