Files
Mdeical_Sur_Report/docs/docker.md

252 lines
8.4 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.
# Docker 化部署
本文档说明如何用 Docker Compose 启动完整系统,以及正式部署前需要替换的配置。第一次安装也可参考 [安装与初始设置](./installation.md)。
## 服务组成
`docker-compose.yaml` 默认启动三个核心服务,另提供一个可选 frpc 服务:
| 服务 | 容器名 | 说明 | 宿主机端口 |
| --- | --- | --- | --- |
| `web` | `tuwen_web` | Nginx 托管前端静态文件,并代理 `/api` 到后端 | `4002``4443` |
| `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_data`PostgreSQL 数据。
- `uploads_data`:报告图片、签名、模板图片、视频和关键帧文件。
## 一键启动
```bash
docker compose up -d --build
```
首次启动时,`api` 容器会自动执行:
1. 等待 PostgreSQL 健康。
2. `prisma migrate deploy`,把 `server/prisma/migrations` 应用到数据库。
3. `prisma db seed`,写入默认医院、部门、账号、模板和系统设置。
4. 启动 NestJS API。
访问地址:
```text
前端 HTTP: http://localhost:4002
前端 HTTPS: https://localhost:4443
API 健康: http://localhost:3002/api/health
```
查看状态:
```bash
docker compose ps
```
查看日志:
```bash
docker compose logs -f api
docker compose logs -f web
docker compose logs -f db
```
停止服务:
```bash
docker compose down
```
连数据库和上传文件一起清空:
```bash
docker compose down -v
```
## 威联通 NAS 部署
<!-- # XXX NAS 部署新增:适用于 QNAP/威联通 Container Station 或 NAS 终端 docker compose 部署。 -->
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://NAS_IP:4002,https://your-domain.example
```
NAS 上的 frpc 隧道:
```bash
# 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 或环境文件中设置:
```yaml
RUN_DB_MIGRATIONS: "false"
RUN_DB_SEED: "false"
```
然后手动执行:
```bash
docker compose exec api npm run prisma:deploy
docker compose exec api npm run prisma:seed
```
## 端口和代理
- 容器内 API 监听 `3100`,宿主机暴露 `3002`
- Nginx 对外暴露 `4002``4443`
- 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` 会生成一个只适合本机演示的自签名证书:
```text
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 来源。
## 公网域名反向代理
<!-- # XXX 公网部署新增:适用于本机 Docker 4002 端口经 frpc 映射到公网服务器,再由 Nginx Proxy Manager 绑定 your-domain.example。 -->
如果使用 `本机 Docker 4002 -> frpc -> 公网服务器 Nginx Proxy Manager -> your-domain.example`,推荐流程:
```bash
# 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;`
`# XXX` 公网正式访问只映射 `4002` 即可;不要把本机自签名 HTTPS 演示入口 `4443` 直接映射为公网域名入口。公网 HTTPS 应由 Nginx Proxy Manager 负责。
公网验收先访问 `https://your-domain.example/api/health`再登录并测试报告保存、视频抽帧、AI 对话和语音听写。
## 生产部署前必须修改
`docker-compose.yaml` 当前适合演示和院内试运行,生产前至少修改:
- `POSTGRES_PASSWORD`:替换默认数据库密码。
- `DATABASE_URL`:与新数据库密码保持一致。
- `SESSION_SECRET`:替换为高强度随机值。
- `CORS_ORIGIN`:只保留真实前端来源。
- `SESSION_COOKIE_SECURE`HTTPS 部署时设为 `true`
- `TRUST_PROXY`:经反向代理提供 HTTPS 时设为 `true`
- `RUN_DB_SEED`:不需要每次启动 seed 时可设为 `false`
- AI/讯飞演示凭据:通过系统设置替换为正式凭据;已经暴露过的密钥应轮换。
- HTTPS 证书:替换自签名本机证书。
## 备份与恢复
数据库备份:
```bash
docker compose exec db pg_dump -U surclaw surclaw > surclaw_backup.sql
```
上传文件备份:
```bash
docker run --rm -v surclaw_system_uploads_data:/data -v "$PWD":/backup alpine \
tar czf /backup/uploads_backup.tgz -C /data .
```
恢复数据库前通常需要停服务或进入维护窗口:
```bash
docker compose exec -T db psql -U surclaw -d surclaw < surclaw_backup.sql
```
## 常见问题
### API 容器一直 unhealthy
查看日志:
```bash
docker compose logs -f api
```
常见原因:
- `DATABASE_URL` 密码和 `POSTGRES_PASSWORD` 不一致。
- 数据库还没健康,等待一段时间或重启 compose。
- migration 失败,需要检查 `server/prisma/migrations`
### 页面能打开但保存失败
检查:
```bash
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` 都没有被调小。
### 语音听写提示麦克风不可用
本机演示使用:
```text
https://localhost:4443
```
局域网 HTTP 访问无法由前端代码绕过浏览器限制,只能配置 HTTPS 或使用 Chrome/Edge 临时演示参数。