Files
Mdeical_Sur_Report/docs/docker.md
admin 8908ebbc4c Document forwarded proto requirements for public HTTPS
- Add Nginx Proxy Manager guidance for X-Forwarded-Proto when secure session cookies are enabled

- Document login Cookie troubleshooting for public HTTPS reverse proxy deployments

- Clarify nginx.conf forwarded-proto behavior for generic and appliance packages
2026-05-09 05:01:50 +08:00

9.2 KiB
Raw Blame History

Docker 化部署

本文档说明如何用 Docker Compose 启动完整系统,以及正式部署前需要替换的配置。第一次安装也可参考 安装与初始设置

服务组成

docker-compose.yaml 默认启动三个核心服务,另提供一个可选 frpc 服务:

服务 容器名 说明 宿主机端口
web tuwen_web Nginx 托管前端静态文件,并代理 /api 到后端 40024443
api tuwen_api NestJS API、Session、AI/语音代理、文件上传 3002
db tuwen_db PostgreSQL 16 5433
frpc tuwen_frpc # XXX 可选公网隧道客户端,通过 --profile frpc 启用 使用 frpc/frpc.toml

持久化 volume

  • postgres_dataPostgreSQL 数据。
  • uploads_data:报告图片、签名、模板图片、视频和关键帧文件。

一键启动

docker compose up -d --build

首次启动时,api 容器会自动执行:

  1. 等待 PostgreSQL 健康。
  2. prisma migrate deploy,把 server/prisma/migrations 应用到数据库。
  3. prisma db seed,写入默认医院、部门、账号、模板和系统设置。
  4. 启动 NestJS API。

访问地址:

前端 HTTP:  http://localhost:4002
前端 HTTPS: https://localhost:4443
API 健康:   http://localhost:3002/api/health

查看状态:

docker compose ps

查看日志:

docker compose logs -f api
docker compose logs -f web
docker compose logs -f db

停止服务:

docker compose down

连数据库和上传文件一起清空:

docker compose down -v

威联通 NAS 部署

NAS 部署可使用仓库内的 docker-compose-Nas.yaml

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 部署时建议设置:

# XXX 生产环境应替换 Session 密钥,并信任 Nginx Proxy Manager/frpc 链路传来的 HTTPS 协议头。
SESSION_SECRET=替换为足够长的随机字符串
SESSION_COOKIE_SECURE=true
TRUST_PROXY=true
CORS_ORIGIN=http://NAS_IP:4002,https://your-domain.example

NAS 上的 frpc 隧道:

# XXX 先编辑 frpc/frpc.nas.toml替换 serverAddr 和 auth.token。
docker compose -f docker-compose-Nas.yaml up -d --build
docker compose -f docker-compose-Nas.yaml logs -f tuwen_frpc

# XXX NAS 版为了适配 Container Station 图形界面会默认创建 tuwen_frpc,不依赖 Compose profile如果不需要公网映射可删除或注释 docker-compose-Nas.yaml 中的 tuwen_frpc 服务。公网正式入口只映射 4002 即可;不要把 4443 自签名 HTTPS 演示端口映射为公网域名入口。公网 HTTPS 应由 Nginx Proxy Manager 提供。

初始化开关

API 容器启动脚本为 scripts/docker-api-entrypoint.sh,可用环境变量控制初始化:

变量 默认值 说明
RUN_DB_MIGRATIONS true 启动 API 前执行 prisma migrate deploy
RUN_DB_SEED true 启动 API 前执行 prisma db seed。当前 seed 使用 upsert不会清空业务数据。
DOCKER_STARTUP_RETRIES 30 migration/seed 等待重试次数。
DOCKER_STARTUP_RETRY_DELAY 2 每次重试间隔秒数。

如果正式环境希望由运维流水线单独执行 migration可在 compose 或环境文件中设置:

RUN_DB_MIGRATIONS: "false"
RUN_DB_SEED: "false"

然后手动执行:

docker compose exec api npm run prisma:deploy
docker compose exec api npm run prisma:seed

端口和代理

  • 容器内 API 监听 3100,宿主机暴露 3002
  • Nginx 对外暴露 40024443
  • Nginx 将 /api/ 反向代理到 api:3100/api/
  • /api/speech/iat 使用同一条 /api 代理路径,并通过 WebSocket upgrade 转发。
  • client_max_body_size 100m 与后端 API_BODY_LIMIT=100mb 对齐,用于图文报告、图片、视频关键帧和 Data URL 上传。

HTTPS 和麦克风

Chrome 不允许普通局域网 HTTP 页面调用麦克风。当前 Dockerfile 会生成一个只适合本机演示的自签名证书:

https://localhost:4443

如果要用局域网 IP 或域名访问语音听写,应替换 Nginx 证书,并让证书包含实际域名/IP。正式环境建议

  • 使用医院内网域名。
  • 通过可信 CA 或内网 CA 签发证书。
  • SESSION_COOKIE_SECURE 设为 true
  • TRUST_PROXY 设为 true# XXX 如果 HTTPS 在 Nginx Proxy Manager、frpc/frps 等外层代理终止,后端需要信任 X-Forwarded-Proto 才能正确写入安全 Cookie。
  • CORS_ORIGIN 改成真实前端 HTTPS 来源。

公网域名反向代理

如果使用 本机 Docker 4002 -> frpc -> 公网服务器 Nginx Proxy Manager -> your-domain.example,推荐流程:

# XXX 使用公网 HTTPS 入口时compose 变量可从 shell 或 .env 覆盖。
export SESSION_SECRET="替换为足够长的随机字符串"
export SESSION_COOKIE_SECURE="true"
export TRUST_PROXY="true"

# XXX 先编辑 frpc/frpc.toml替换 serverAddr 和 auth.token再启用 frpc profile。
docker-compose --profile frpc up -d --build
docker-compose logs -f frpc

Nginx Proxy Manager 配置要点:

  • Domain Names 使用 your-domain.example
  • Forward Hostname / IP 指向 frpc 在公网服务器暴露的地址。
  • Forward Port 填 frpc 暴露的端口,例如 4002
  • 开启 Websockets Support,保证 /api/speech/iat 语音听写 WebSocket 可升级。
  • SSL 页签绑定证书并开启 Force SSL,保证浏览器开放麦克风权限。
  • Advanced 中建议设置 client_max_body_size 100m;proxy_read_timeout 3600s;proxy_send_timeout 3600s;
  • Advanced 中建议显式传递公网 HTTPS 协议,避免 SESSION_COOKIE_SECURE=true 时后端无法写入登录 Cookie
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;

# XXX 公网正式访问只映射 4002 即可;不要把本机自签名 HTTPS 演示入口 4443 直接映射为公网域名入口。公网 HTTPS 应由 Nginx Proxy Manager 负责。

公网验收先访问 https://your-domain.example/api/health再登录并测试报告保存、视频抽帧、AI 对话和语音听写。

如果公网登录后仍提示“未登录”,或系统设置等后端操作报 401

  1. 在浏览器 Network 中查看 POST /api/auth/login 是否为 200
  2. 检查该响应是否有 Set-Cookie: surclaw.sid=...
  3. 如果登录为 200 但没有 Set-Cookie,说明后端没有确认当前请求是 HTTPS确认 SESSION_COOKIE_SECURE=trueTRUST_PROXY=true,并在外层 Nginx Proxy Manager Advanced 中补充 proxy_set_header X-Forwarded-Proto https;
  4. 修改代理或 nginx.conf 后需要重建/重启 web,修改 API 环境变量后需要重建/重启 api

生产部署前必须修改

docker-compose.yaml 当前适合演示和院内试运行,生产前至少修改:

  • POSTGRES_PASSWORD:替换默认数据库密码。
  • DATABASE_URL:与新数据库密码保持一致。
  • SESSION_SECRET:替换为高强度随机值。
  • CORS_ORIGIN:只保留真实前端来源。
  • SESSION_COOKIE_SECUREHTTPS 部署时设为 true
  • TRUST_PROXY:经反向代理提供 HTTPS 时设为 true
  • RUN_DB_SEED:不需要每次启动 seed 时可设为 false
  • AI/讯飞演示凭据:通过系统设置替换为正式凭据;已经暴露过的密钥应轮换。
  • HTTPS 证书:替换自签名本机证书。

备份与恢复

数据库备份:

docker compose exec db pg_dump -U surclaw surclaw > surclaw_backup.sql

上传文件备份:

docker run --rm -v surclaw_system_uploads_data:/data -v "$PWD":/backup alpine \
  tar czf /backup/uploads_backup.tgz -C /data .

恢复数据库前通常需要停服务或进入维护窗口:

docker compose exec -T db psql -U surclaw -d surclaw < surclaw_backup.sql

常见问题

API 容器一直 unhealthy

查看日志:

docker compose logs -f api

常见原因:

  • DATABASE_URL 密码和 POSTGRES_PASSWORD 不一致。
  • 数据库还没健康,等待一段时间或重启 compose。
  • migration 失败,需要检查 server/prisma/migrations

页面能打开但保存失败

检查:

curl http://localhost:4002/api/health
curl http://localhost:3002/api/health
docker compose logs -f api

如果报告图片或关键帧很大,确认 API_BODY_LIMIT 和 Nginx client_max_body_size 都没有被调小。

语音听写提示麦克风不可用

本机演示使用:

https://localhost:4443

局域网 HTTP 访问无法由前端代码绕过浏览器限制,只能配置 HTTPS 或使用 Chrome/Edge 临时演示参数。