Files
Mdeical_Sur_Report/docs/deployment.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

164 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 部署运行
如果是第一次安装项目,建议先阅读 [安装与初始设置](./installation.md)。Docker Compose 的完整一键部署、健康检查、初始化脚本和生产变量见 [Docker 化部署](./docker.md)。本文档主要记录开发运行、质量检查、环境变量和 Docker/Nginx 部署边界。
## 本地开发
前端:
```bash
npm install
npm run dev
```
开发服务监听 `0.0.0.0:3001`
开发模式下 Vite 会把 `/api` 代理到 `VITE_API_PROXY_TARGET`,默认 `http://localhost:3100`
后端:
```bash
cp .env.example .env
npm run prisma:generate
npm run server:dev
```
本地直接运行 API 默认监听 `0.0.0.0:3100`,健康检查为:
```text
http://localhost:3100/api/health
```
如需连接真实 PostgreSQL
```bash
npm run prisma:migrate
npm run prisma:seed
```
## 质量检查
```bash
npm run lint
npm run test
npm run server:build
npm run build
```
当前 `lint` 实际执行 `tsc --noEmit`,用于 TypeScript 类型检查。
## 环境变量
复制示例文件:
```bash
cp .env.example .env.local
```
AI 和语音密钥由后端 Settings API 保存并由代理使用,前端不再注入 Gemini 旧环境变量。
后端新增变量:
- `API_PORT`API 监听端口。本地直接运行默认 `3100`Docker Compose 暴露到宿主机的默认端口是 `3002`
- `API_BODY_LIMIT`API JSON/urlencoded 请求体上限,默认 `100mb`。报告正文、关键帧、模板图片和通用文件上传仍可能携带 Data URL调小会导致保存或上传出现 `request entity too large`
- `CORS_ORIGIN`:允许跨域携带 Cookie 的前端来源。
- `DATABASE_URL`PostgreSQL 连接串。Docker Compose 暴露到宿主机的默认端口是 `5433`,容器内部仍使用 `db:5432`
- `SESSION_SECRET`Session Cookie 签名密钥。
- `SESSION_COOKIE_SECURE`:是否只通过 HTTPS 发送 Session Cookie。本地 HTTP/Compose 默认 `false`,生产 HTTPS 应设为 `true`
- `TRUST_PROXY`:是否信任反向代理传入的 `X-Forwarded-*` 头。`# XXX` 公网 HTTPS 经过 Nginx Proxy Manager、frpc/frps 或其他反向代理转发时建议设为 `true`
- `FILE_STORAGE_DIR`后端文件目录。Docker Compose 默认 `/app/uploads`,并挂载到 `uploads_data` volume。
- `RUN_DB_MIGRATIONS`Docker API 容器启动时是否执行 `prisma migrate deploy`,默认 `true`
- `RUN_DB_SEED`Docker API 容器启动时是否执行 `prisma db seed`,默认 `true`
- `DOCKER_STARTUP_RETRIES` / `DOCKER_STARTUP_RETRY_DELAY`Docker API 启动脚本等待数据库、migration 和 seed 的重试次数与间隔。
- `VITE_API_PROXY_TARGET`:前端开发服务器 `/api` 代理目标。直接运行后端用 `http://localhost:3100`;连接 Docker Compose API 用 `http://localhost:3002`
- `VITE_ENABLE_LOCAL_FALLBACK`:生产构建是否允许本地兼容回退。开发模式默认启用,生产默认关闭。
## Docker 部署
```bash
docker-compose up -d --build
```
默认通过 Nginx 暴露 `http://localhost:4002`,并额外暴露自签名证书的语音演示入口 `https://localhost:4443`
当前 Compose 服务:
- `web`:前端静态站点,暴露 `http://localhost:4002``https://localhost:4443`
- `api`NestJS API暴露 `http://localhost:3002`
- `db`PostgreSQL 16暴露 `localhost:5433`
- `frpc``# XXX` 可选公网隧道客户端,通过 `--profile frpc` 启用,读取 `frpc/frpc.toml` 把本机 `4002` 映射到公网 frps。
- `uploads_data`:后端文件持久化 volume。
`api` 容器启动时默认会等待数据库健康,执行 `prisma migrate deploy``prisma db seed`,再启动 NestJS API。可通过 `RUN_DB_MIGRATIONS``RUN_DB_SEED` 关闭自动初始化。
构建流程:
- `Dockerfile` 使用 Node 构建 `dist/`
- 运行阶段使用 `nginx:alpine` 托管静态文件。
- `Dockerfile.server` 构建并运行 NestJS API。
- `nginx.conf` 已配置 SPA 路由回退、`/api` 反向代理、`100m` 请求体上限和自签名 HTTPS 演示入口。
更完整的 Docker 说明、生产变量、证书和备份恢复见 [Docker 化部署](./docker.md)。
## 公网反向代理
<!-- # XXX 公网部署新增:适用于本机 Docker 4002 端口经 frpc 映射到公网服务器,再由 Nginx Proxy Manager 绑定域名。 -->
推荐链路:
```text
浏览器 https://your-domain.example
-> 公网服务器 Nginx Proxy Manager
-> frps/frpc 映射端口
-> 本机 Docker web:4002
-> 容器 Nginx /api
-> api:3100
```
公网部署建议变量:
```bash
# XXX HTTPS 生产入口建议开启安全 Cookie并让后端信任外层代理协议头。
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 代理 `your-domain.example` 时:
- 代理目标指向 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;`
- `SESSION_COOKIE_SECURE=true` 时,后端还必须收到 `X-Forwarded-Proto: https`。如果登录接口返回 200 但响应头没有 `Set-Cookie`,或刷新后 `/api/auth/me` 返回 `401 未登录`,在 Advanced 中补充:
```nginx
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
```
`# XXX` 公网正式访问只映射 `4002` 即可;不要把 Docker 自签名 HTTPS 演示入口 `4443` 映射到公网域名。
## 麦克风访问
浏览器不允许普通局域网 HTTP 页面调用麦克风代码无法绕过这个限制。Docker 演示环境建议使用:
```text
https://localhost:4443
```
首次打开会看到自签名证书提示,接受后即可让浏览器开放麦克风权限。如果必须用 `http://局域网IP:4002` 演示,只能在 Chrome/Edge 启动时加临时参数,把该 HTTP 来源标记为可信:
```bash
google-chrome --unsafely-treat-insecure-origin-as-secure=http://局域网IP:4002 --user-data-dir=/tmp/surclaw-chrome-demo
```
这是浏览器演示开关,不是系统安全方案;正式环境仍建议使用 HTTPS。
## 部署边界
当前后端已承载登录认证、数据库 Session、Dashboard、报告、报告媒体关系、模板、字段库、通用文件/签名文件、视频/关键帧文件、用户管理、部门模板授权、系统设置、AI 代理、语音代理、HTML 清洗和审计日志查询。生产化前还需要补齐第三方代理调用摘要、限流、备份恢复、对象存储和更完整的旧数据迁移。