Complete Docker compose deployment setup
- Add an API container entrypoint that waits for PostgreSQL, runs Prisma migrations, seeds demo data, and then starts NestJS. - Keep Prisma CLI and seed dependencies available in the API runtime image and copy seed source dependencies into the container. - Add Docker Compose healthchecks and health-based startup ordering for PostgreSQL, API, and Nginx web services. - Add Docker initialization environment switches for migrations, seed, and startup retries. - Add a dedicated Docker deployment guide covering services, ports, initialization, HTTPS, production variables, backup, restore, and troubleshooting. - Update README, AGENTS, installation, deployment, progress, and environment example docs for the Dockerized workflow.
This commit is contained in:
185
docs/docker.md
Normal file
185
docs/docker.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# Docker 化部署
|
||||
|
||||
本文档说明如何用 Docker Compose 启动完整系统,以及正式部署前需要替换的配置。第一次安装也可参考 [安装与初始设置](./installation.md)。
|
||||
|
||||
## 服务组成
|
||||
|
||||
`docker-compose.yaml` 启动三个服务:
|
||||
|
||||
| 服务 | 容器名 | 说明 | 宿主机端口 |
|
||||
| --- | --- | --- | --- |
|
||||
| `web` | `tuwen_web` | Nginx 托管前端静态文件,并代理 `/api` 到后端 | `4002`、`4443` |
|
||||
| `api` | `tuwen_api` | NestJS API、Session、AI/语音代理、文件上传 | `3002` |
|
||||
| `db` | `tuwen_db` | PostgreSQL 16 | `5433` |
|
||||
|
||||
持久化 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
|
||||
```
|
||||
|
||||
## 初始化开关
|
||||
|
||||
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`。
|
||||
- 把 `CORS_ORIGIN` 改成真实前端 HTTPS 来源。
|
||||
|
||||
## 生产部署前必须修改
|
||||
|
||||
`docker-compose.yaml` 当前适合演示和院内试运行,生产前至少修改:
|
||||
|
||||
- `POSTGRES_PASSWORD`:替换默认数据库密码。
|
||||
- `DATABASE_URL`:与新数据库密码保持一致。
|
||||
- `SESSION_SECRET`:替换为高强度随机值。
|
||||
- `CORS_ORIGIN`:只保留真实前端来源。
|
||||
- `SESSION_COOKIE_SECURE`: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 临时演示参数。
|
||||
Reference in New Issue
Block a user