docs(dobotai): add container deployment guide
This commit is contained in:
@@ -1,29 +1,153 @@
|
||||
# DobotAI 容器化运行(测试环境)
|
||||
# DobotAI DingTalk 容器部署手册
|
||||
|
||||
容器和Compose服务固定名为 `dobotai-dingtalk`。容器使用宿主网络,以兼容测试环境已有的 `127.0.0.1` PostgreSQL、WeKnora和健康检查地址;它不暴露新端口,不更改数据库容器或WeKnora容器。
|
||||
> 适用范围:DobotAI 测试环境的容器化运行。容器和 Compose 服务名固定为 `dobotai-dingtalk`。
|
||||
> 本文不授权生产部署;生产必须使用已验收的同一镜像、独立备份和独立变更审批。
|
||||
|
||||
## 日常操作
|
||||
## 1. 定位
|
||||
|
||||
完成一次安装后,日常仅需要两条命令:
|
||||
DobotAI 是钉钉渠道的对话编排与交付层,不是知识库或文档解析平台。
|
||||
|
||||
它负责:
|
||||
|
||||
- 接收钉钉 Stream 消息、富文本和图片;
|
||||
- 将请求路由到 WeKnora Agent,并维护渠道会话;
|
||||
- 通过钉钉 AI 卡片或 Markdown 流式交付回答;
|
||||
- 处理 `/think`、`/setting` 等渠道命令;
|
||||
- 保存 Turn、会话映射、覆盖判定、Support Case、反馈和审计数据;
|
||||
- 对“真实检索过但没有引用”的回答创建未覆盖提醒;
|
||||
- 将 `resource://` 图片按私有 OSS 规则安全外发。
|
||||
|
||||
它不负责:
|
||||
|
||||
- WeKnora 文档、Chunk、向量、图谱、解析或模型运行;
|
||||
- WeKnora Agent 的知识检索策略;
|
||||
- 直接暴露 PostgreSQL、WeKnora 或对象存储到公网;
|
||||
- 替代钉钉应用、机器人或群权限配置。
|
||||
|
||||
## 2. 架构
|
||||
|
||||
```text
|
||||
钉钉用户 / 群
|
||||
│ DingTalk Stream
|
||||
▼
|
||||
┌──────────────────────────────────────┐
|
||||
│ dobotai-dingtalk 容器 │
|
||||
│ - 消息解析、会话编排、卡片流式交付 │
|
||||
│ - /think、/setting、首位管理员绑定 │
|
||||
│ - 覆盖判定、Support Case、审计 │
|
||||
└───────┬──────────────────┬───────────┘
|
||||
│ │
|
||||
│ HTTP Agent Chat │ PostgreSQL
|
||||
▼ ▼
|
||||
WeKnora 服务 DobotAI 独立数据库
|
||||
- Agent/检索 - Turn / 会话 / 覆盖判定
|
||||
- 文档/Chunk - Support Case / 反馈 / 设置
|
||||
- 模型与解析
|
||||
```
|
||||
|
||||
### 2.1 容器边界
|
||||
|
||||
| 资源 | 归属 | 是否由本容器创建/删除 |
|
||||
| --- | --- | --- |
|
||||
| `dobotai-dingtalk` | DobotAI应用进程 | 是,容器可重建 |
|
||||
| DobotAI PostgreSQL | 独立数据服务 | 否,保留现有数据卷 |
|
||||
| WeKnora | 独立知识服务 | 否 |
|
||||
| `/var/lib/dobotai-test/secrets` | 宿主机密钥目录 | 仅挂载读写,不迁移、不输出 |
|
||||
| `/etc/dobotai-test/dobotai.env` | 受保护运行配置 | Docker读取,脚本原子更新 |
|
||||
|
||||
测试环境的 PostgreSQL、WeKnora 已通过宿主机回环地址提供服务,因此 Compose 使用 `network_mode: host`。这不是新开公网端口:DobotAI仍按 `DOBOTAI_LISTEN_ADDR` 监听,默认是 `127.0.0.1:8090`。
|
||||
|
||||
### 2.2 容器安全属性
|
||||
|
||||
Compose 固定启用:
|
||||
|
||||
```text
|
||||
容器名:dobotai-dingtalk
|
||||
网络:host(仅兼容现有测试宿主机回环依赖)
|
||||
运行身份:与原 dobotai-test 服务用户相同的 UID:GID
|
||||
根文件系统:只读
|
||||
临时写入:仅 /tmp tmpfs
|
||||
额外权限:no-new-privileges
|
||||
重启策略:unless-stopped
|
||||
```
|
||||
|
||||
对应的关键 Compose 配置如下;不要为避免端口冲突额外添加 `ports:` 映射:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
dobotai-dingtalk:
|
||||
container_name: dobotai-dingtalk
|
||||
network_mode: host
|
||||
read_only: true
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
## 3. 安装前检查
|
||||
|
||||
安装操作人员需要具备测试服务器的 `sudo` 和 Docker 权限。开始前确认:
|
||||
|
||||
```text
|
||||
1. 已构建或导入经审查的 DobotAI 镜像;
|
||||
2. 现有 /etc/dobotai-test/dobotai.env 存在且权限为 0600;
|
||||
3. 现有密钥目录 /var/lib/dobotai-test/secrets 存在;
|
||||
4. DobotAI PostgreSQL 与 WeKnora 已健康;
|
||||
5. 已记录当前原生服务二进制SHA和运行状态;
|
||||
6. 如本版本包含 SQL 迁移,已先完成逻辑备份与迁移演练。
|
||||
```
|
||||
|
||||
不要执行:
|
||||
|
||||
```text
|
||||
docker compose down -v
|
||||
docker volume rm / prune
|
||||
删除 PostgreSQL / WeKnora 数据卷
|
||||
将密钥、数据库连接串或 API Key 写入命令行、日志或 Git
|
||||
```
|
||||
|
||||
## 4. 构建和导入镜像
|
||||
|
||||
在已审查且工作树干净的源码目录构建。示例中的值均为占位符:
|
||||
|
||||
```bash
|
||||
docker build \
|
||||
--build-arg VERSION=test-<commit-short> \
|
||||
--build-arg COMMIT_SHA=<完整提交SHA> \
|
||||
--build-arg BUILD_TIME=<UTC时间> \
|
||||
-t dobotai-dingtalk:test-<commit-short> .
|
||||
```
|
||||
|
||||
跨主机传输时先保存镜像归档并记录 SHA-256;测试服务器导入后必须复核归档哈希和镜像标签。生产不得在目标机重新编译,应使用已测试的同一镜像归档或不可变镜像摘要。
|
||||
|
||||
## 5. 安装容器资产(不切换服务)
|
||||
|
||||
将本目录、候选镜像和已核验的归档放到测试服务器的受控发布目录。确认镜像已经 `docker load` 后执行:
|
||||
|
||||
```bash
|
||||
sudo DOBOTAI_IMAGE=dobotai-dingtalk:test-<commit-short> \
|
||||
bash ./install-test.sh
|
||||
```
|
||||
|
||||
该脚本会:
|
||||
|
||||
```text
|
||||
1. 检查候选镜像、现有 env 与密钥目录;
|
||||
2. 备份原生 DobotAI 二进制和 systemd Unit,并写入 SHA-256;
|
||||
3. 安装 Compose、配置器、启动器和绑定脚本;
|
||||
4. 生成权限 0600 的 /opt/dobotai-test/container/runtime.env;
|
||||
5. 保持原生 dobotai-test.service 继续运行。
|
||||
```
|
||||
|
||||
它不会读取或打印环境变量值、不会修改数据库、不会启动容器。
|
||||
|
||||
## 6. 配置并启动
|
||||
|
||||
日常只需要执行:
|
||||
|
||||
```bash
|
||||
sudo dobotai-dingtalk-configure
|
||||
sudo dobotai-dingtalk-bind-admin
|
||||
```
|
||||
|
||||
第一条命令以隐藏输入方式更新 `/etc/dobotai-test/dobotai.env` 中的必填配置;不会将秘密传入命令行、终端输出或Git。环境文件写入成功后,它会受控停止原生 `dobotai-test.service`、启动 `dobotai-dingtalk`,并以 `/healthz` 验证。容器健康检查失败时自动停止容器并恢复原生服务。
|
||||
|
||||
第二条命令在已运行的容器内执行 `dobotai bootstrap-admin`。终端显示六码后,候选管理员私聊钉钉机器人:
|
||||
|
||||
```text
|
||||
/setting <六码>
|
||||
```
|
||||
|
||||
绑定成功后终端自动退出。该命令不会启动第二个钉钉 Stream 消费者。
|
||||
|
||||
## 配置项说明与示例
|
||||
|
||||
`sudo dobotai-dingtalk-configure` 会在每个输入项前显示相同的说明和示例。现有值永不显示;提示“已配置”时直接回车即可保留原值。秘密项以隐藏输入读取,以下示例均为脱敏占位符。
|
||||
该命令交互更新 `/etc/dobotai-test/dobotai.env`。每项都会显示用途和脱敏格式示例;已配置的值永不回显,直接回车表示保留。
|
||||
|
||||
| 环境变量 | 用途 | 格式示例 |
|
||||
| --- | --- | --- |
|
||||
@@ -36,6 +160,121 @@ sudo dobotai-dingtalk-bind-admin
|
||||
| `DINGTALK_CLIENT_ID` | 钉钉应用Client ID/AppKey | `dingxxxxxxxx` |
|
||||
| `DINGTALK_CLIENT_SECRET` | 钉钉应用Client Secret/AppSecret | `<你的钉钉 AppSecret>` |
|
||||
|
||||
## 安装前置条件
|
||||
保存成功后,配置器自动调用启动器:
|
||||
|
||||
安装脚本只接受已构建、已审查的本地镜像,并在切换前备份原生二进制与Systemd Unit。它不读取或打印环境文件中的值,也不停止旧服务。生产环境必须独立审查、备份和验证,不复用测试镜像以外的未验证构建。
|
||||
```text
|
||||
停止原生 dobotai-test.service
|
||||
→ 启动 dobotai-dingtalk
|
||||
→ 检查 http://127.0.0.1:8090/healthz
|
||||
→ 健康成功后禁用原生服务
|
||||
```
|
||||
|
||||
首次容器启动失败会恢复原生服务;容器版本升级失败会恢复上一容器镜像。
|
||||
|
||||
## 7. 首位管理员绑定
|
||||
|
||||
仅当该租户不存在有效管理员时执行:
|
||||
|
||||
```bash
|
||||
sudo dobotai-dingtalk-bind-admin
|
||||
```
|
||||
|
||||
终端会显示一个10分钟有效的随机六码。候选管理员必须私聊钉钉机器人发送:
|
||||
|
||||
```text
|
||||
/setting <六码绑定码>
|
||||
```
|
||||
|
||||
验证成功后,终端自动写入 `super_admin/active` 并退出。已有有效管理员时命令拒绝执行,防止借由该入口追加管理员或意外提权。
|
||||
|
||||
## 8. 覆盖判定与未覆盖提醒
|
||||
|
||||
覆盖判定基于真实的 `knowledge_searched` 工具事件和结构化引用,不按关键词猜测。
|
||||
|
||||
| 场景 | 覆盖结果 | 是否创建 Support Case |
|
||||
| --- | --- | --- |
|
||||
| 有引用 | `covered_has_references` | 否 |
|
||||
| 实际检索过但无引用 | `uncovered_no_references` | 是 |
|
||||
| 明确无权威知识/无答案 | `uncovered_explicit_no_answer` | 是 |
|
||||
| 图片未检索、纯视觉识别 | `covered_visual_recognition` | 否 |
|
||||
| 文本未检索、闲聊或普通非知识响应 | `covered_non_knowledge_response` | 否 |
|
||||
|
||||
因此“在吗”“你好”“谢谢”等未触发知识检索的文本不会产生未覆盖提醒;真正检索过但没有权威引用的问题仍会进入人工支持流程。
|
||||
|
||||
## 9. 数据库迁移门禁
|
||||
|
||||
DobotAI进程只连接数据库,**不会自动发现或执行 SQL 迁移**。包含新迁移的版本必须在容器替换前由发布流程显式完成:
|
||||
|
||||
```text
|
||||
1. 对 DobotAI PostgreSQL 做逻辑备份;
|
||||
2. 使用 pg_restore --list 验证备份非空;
|
||||
3. 在事务中执行已审查的 .up.sql;
|
||||
4. 向 dobotai_schema_migrations 写入对应 version/name/applied_at;
|
||||
5. 查询约束、列或索引确认生效;
|
||||
6. 再替换容器镜像并进行健康与业务验收。
|
||||
```
|
||||
|
||||
`000021_coverage_non_knowledge_response_reason` 是一个示例:它只扩展 `coverage_decisions.reason_code` 的 CHECK 约束,不回写历史Turn、覆盖判定或Support Case。
|
||||
|
||||
## 10. 日常检查
|
||||
|
||||
```bash
|
||||
# 健康检查
|
||||
curl --noproxy '*' -fsS http://127.0.0.1:8090/healthz
|
||||
|
||||
# 运行版本
|
||||
curl --noproxy '*' -fsS http://127.0.0.1:8090/version
|
||||
|
||||
# 容器状态与重启次数
|
||||
sudo docker inspect -f '{{.Config.Image}}|{{.State.Running}}|{{.RestartCount}}' dobotai-dingtalk
|
||||
|
||||
# 最近日志(不要复制含敏感内容的原始上下文)
|
||||
sudo docker logs --since 10m dobotai-dingtalk
|
||||
```
|
||||
|
||||
验收至少应同时满足:
|
||||
|
||||
```text
|
||||
容器 running,重启次数为0;
|
||||
/healthz 返回 ok;
|
||||
/version 的 commit_sha 与发布记录一致;
|
||||
钉钉 Stream 仅启动一个消费者;
|
||||
旧 dobotai-test.service 为 inactive + disabled;
|
||||
目标业务路径已由真实钉钉消息验证。
|
||||
```
|
||||
|
||||
## 11. 升级与回滚
|
||||
|
||||
### 升级
|
||||
|
||||
```text
|
||||
构建/导入经审查的新镜像
|
||||
→ 备份DobotAI PostgreSQL
|
||||
→ 应用并记录必要迁移
|
||||
→ 将 runtime.env 中的 DOBOTAI_IMAGE 更新为新标签
|
||||
→ 执行 sudo dobotai-dingtalk-start
|
||||
→ 健康、版本、日志、钉钉真实消息验收
|
||||
```
|
||||
|
||||
注意拼写:数据库和应用名称是 `DobotAI`;上述流程中的镜像名为 `dobotai-dingtalk`。
|
||||
|
||||
### 自动回滚
|
||||
|
||||
启动器会保存替换前的容器镜像:
|
||||
|
||||
```text
|
||||
首次容器化失败:停止候选容器,恢复原生服务;
|
||||
后续容器升级失败:停止候选容器,恢复上一容器镜像。
|
||||
```
|
||||
|
||||
数据库迁移不能仅靠容器回滚撤销。只有经过审查且已验证的 `.down.sql` 才可用于数据库回滚;任何数据恢复都必须先确认备份可用。
|
||||
|
||||
## 12. 明确非目标
|
||||
|
||||
```text
|
||||
不容器化或重建 WeKnora;
|
||||
不容器化或删除 DobotAI PostgreSQL;
|
||||
不重新启用已删除的网页管理面;
|
||||
不在生产环境复用测试凭据、测试镜像或未验收的迁移;
|
||||
不把密钥、Token、连接串、钉钉凭据写入 Git、命令行或日志。
|
||||
```
|
||||
Reference in New Issue
Block a user