```
feat(learning): 添加技能学习候选者合成锁定机制 添加了 DraftSynthesisInProgress 和 DraftHasNoChanges 异常来处理并发场景, 确保同一技能学习候选者的合成过程不会重复执行。实现了 claim_learning_candidate_for_synthesis 方法来原子性地锁定候选者进行合成。 fix(web): 为技能草案创建端点添加适当的HTTP状态码 当草案没有变化或正在合成时,现在正确返回409状态码而不是内部错误。 feat(skills): 实现技能修订内容比较以检测无变化情况 添加了 _is_noop_revision 方法来比较基础技能和提议的修订, 如果内容没有实际变化则抛出 NoDraftChanges 异常。 refactor(process): 修复任务证据记录后根运行状态更新逻辑 将任务证据记录事件后的状态从 waiting 更改为 done,并设置 finished_at 时间戳。 feat(tools): 防止在同一运行中重复执行外部写入操作 为邮件发送、日历创建等外部写入工具添加去重机制,避免重复的外部操作。 test: 添加技能学习和工具执行的单元测试 增加测试用例验证并发草案合成、重复外部写入抑制和无变化修订检测等功能。 ```
This commit is contained in:
42
部署指南.md
42
部署指南.md
@ -1,11 +1,14 @@
|
||||
# Beaver Project 本机部署指南
|
||||
|
||||
最后更新:2026-06-16。
|
||||
|
||||
这份文档用于在一台 Linux 或 WSL2 Ubuntu 机器上跑完整链路:
|
||||
|
||||
- `auth-portal`
|
||||
- `authz-service`
|
||||
- `deploy-control`
|
||||
- `router-proxy`
|
||||
- `MinIO` 用户文件后端
|
||||
- 可选的 `external-connector` sidecar
|
||||
- 自动创建出来的 `app-instance`
|
||||
|
||||
@ -17,6 +20,14 @@
|
||||
|
||||
如果你只单独启动某个前端页面,页面可以打开,但注册、登录、创建实例这些动作不一定能通。
|
||||
|
||||
当前部署链路的几个关键状态:
|
||||
|
||||
- 注册阶段只创建实例和账号,不再写入模型 provider、model 或 API key。
|
||||
- 注册成功后由 `auth-portal` 的模型配置引导调用 `deploy-control /api/instances/configure-provider` 写入模型配置并重启实例;跳过引导也可以先进入实例。
|
||||
- 用户文件系统由 Beaver API 代理到 MinIO/S3,前端不会直接接触 bucket、prefix、access key 或 secret key。
|
||||
- `external-connector` 是微信、飞书/Lark 等通道的 sidecar;不使用这些通道时可以跳过,但新实例是否带连接器环境变量取决于创建实例时的 `deploy-control` 环境。
|
||||
- 新实例会从 `$PROJECT_ROOT/skills` 种入初始 published skills;`deploy-control` 容器必须以相同绝对路径只读挂载该目录。
|
||||
|
||||
## 0. 前提
|
||||
|
||||
推荐环境:
|
||||
@ -184,6 +195,8 @@ beaver-deploy-control:8090
|
||||
|
||||
如果改的是 `BEAVER_BASE_DOMAIN`,还要重启 `beaver-deploy-control`。这个变量只影响之后新创建的实例;已经创建过的实例 URL 已经写入 `app-instance/runtime/registry/instances.json`,不会自动改成新域名。
|
||||
|
||||
不要把 `BEAVER_BASE_DOMAIN` 设置成裸 IP,除非你明确想让实例走直连端口模式。`deploy-control` 检测到 `DEPLOY_PUBLIC_BASE_DOMAIN` 是 IP 时,会为每个实例分配 `20000-29999` 里的独立宿主机端口并生成 `http://<IP>:<host_port>` 形式的 URL;这会绕过按 Host 分发的 `router-proxy` 域名入口。正式环境推荐使用真实域名,例如 `apps.example.com`。
|
||||
|
||||
### 非本机访问怎么配置域名
|
||||
|
||||
如果 Beaver 部署在服务器上,而用户从其他机器访问,不要使用 `localhost`。推荐准备一个真实域名,并把通配子域名解析到服务器,例如:
|
||||
@ -427,12 +440,15 @@ docker run -d \
|
||||
-e DEPLOY_PUBLIC_SCHEME="http" \
|
||||
-e DEPLOY_PUBLIC_BASE_DOMAIN="$BEAVER_BASE_DOMAIN" \
|
||||
-e DEPLOY_PUBLIC_PORT="8088" \
|
||||
-e DEPLOY_DIRECT_PUBLIC_HOST_BIND_IP="0.0.0.0" \
|
||||
-e DEPLOY_AUTO_START_PROXY="1" \
|
||||
beaver/deploy-control:latest
|
||||
```
|
||||
|
||||
`DEPLOY_PUBLIC_BASE_DOMAIN` 来自 `BEAVER_BASE_DOMAIN`。本机测试时可以是 `localhost`;如果要让其他设备访问,必须换成它们能解析到 Beaver 服务器的真实域名。修改后需要重启 `beaver-deploy-control`,并重新创建实例或手动更新 registry 后重载 `router-proxy`。
|
||||
|
||||
`DEPLOY_DIRECT_PUBLIC_HOST_BIND_IP` 只在 `DEPLOY_PUBLIC_BASE_DOMAIN` 是裸 IP 时生效,用来控制每个实例直连端口绑定在哪个宿主机地址。正常域名部署不依赖这个变量,实例流量应走 `router-proxy:8088`。
|
||||
|
||||
当前版本创建实例时会传 `--skip-provider-config`,也就是先不写 provider、model 或 API key。注册成功后,`auth-portal` 会进入模型配置引导页,再调用 `deploy-control /api/instances/configure-provider` 写入该实例的 `config.json` 并重启容器。
|
||||
|
||||
`DEFAULT_AUTHZ_INTERNAL_TOKEN` 会写入新建 app-instance 的后端 runtime env,用于 app-instance 后端读取自己的 internal MinIO settings。它不会传给前端。
|
||||
@ -441,6 +457,8 @@ docker run -d \
|
||||
|
||||
`DEFAULT_INITIAL_SKILLS_DIR` 需要和 `skills/` 的只读挂载路径一致。否则新实例能启动,但 workspace 里不会自动种入初始 published skills。
|
||||
|
||||
如果是在实例创建后才更新 `$PROJECT_ROOT/skills` 里的初始 skills,已有实例不会自动同步这批初始文件。需要按实例使用 `scripts/deploy-initial-skills.sh` 或在实例内走 skills 管理/发布流程。
|
||||
|
||||
## 11. 启动 auth-portal
|
||||
|
||||
```bash
|
||||
@ -477,6 +495,8 @@ docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
|
||||
docker logs --tail=50 beaver-router-proxy
|
||||
```
|
||||
|
||||
公网或局域网正式部署时,通常只应该对外开放 `80/443`,由外层代理转发到 `3081` 和 `8088`。`8090`、`19090`、`9000/9001`、`8787` 以及实例直连端口 `20000-29999` 默认都应限制在本机、容器网络或可信内网。
|
||||
|
||||
至少应该看到这些容器:
|
||||
|
||||
- `beaver-authz-service`
|
||||
@ -715,7 +735,7 @@ cd "$PROJECT_ROOT/app-instance"
|
||||
docker ps --format 'table {{.Names}}\t{{.Status}}' | grep app-instance
|
||||
```
|
||||
|
||||
排查 URL 变量:
|
||||
排查部署变量:
|
||||
|
||||
```bash
|
||||
docker inspect beaver-authz-service --format '{{range .Config.Env}}{{println .}}{{end}}' \
|
||||
@ -725,10 +745,10 @@ docker inspect beaver-auth-portal --format '{{range .Config.Env}}{{println .}}{{
|
||||
| egrep '^(AUTHZ_API_BASE_URL|DEPLOY_API_BASE_URL)='
|
||||
|
||||
docker inspect beaver-deploy-control --format '{{range .Config.Env}}{{println .}}{{end}}' \
|
||||
| egrep '^(DEFAULT_EXTERNAL_CONNECTOR_BASE_URL|DEFAULT_EXTERNAL_CONNECTOR_TOKEN|DEFAULT_BEAVER_BRIDGE_TOKEN|DEFAULT_INITIAL_SKILLS_DIR)='
|
||||
| egrep '^(DEPLOY_PUBLIC_|DEPLOY_DIRECT_PUBLIC_HOST_BIND_IP|DEFAULT_EXTERNAL_CONNECTOR_BASE_URL|DEFAULT_EXTERNAL_CONNECTOR_TOKEN|DEFAULT_BEAVER_BRIDGE_TOKEN|DEFAULT_INITIAL_SKILLS_DIR)='
|
||||
```
|
||||
|
||||
它们都必须是完整 URL,不能是空字符串,也不能是裸 `host:port`。
|
||||
其中 `AUTHZ_*_BASE_URL`、`DEPLOY_API_BASE_URL`、`DEFAULT_EXTERNAL_CONNECTOR_BASE_URL` 这类 URL 必须带 `http://` 或 `https://`,不能是裸 `host:port`。token 变量不能为空;`DEFAULT_INITIAL_SKILLS_DIR` 必须对应 `deploy-control` 容器里真实存在、且和宿主机一致的绝对路径。
|
||||
|
||||
## 17. 常见问题
|
||||
|
||||
@ -857,6 +877,22 @@ EXTERNAL_CONNECTOR_CALLBACK_BASE_URL=http://app-instance-alice:8080
|
||||
|
||||
如果它为空,通常是实例创建时没有传 `--network "$BEAVER_NET"`,或者旧实例是在连接器变量加入前创建的。重新创建实例,或用同样的实例数据目录手工重建容器。
|
||||
|
||||
### 使用裸 IP 做 BEAVER_BASE_DOMAIN 后 URL 变成直连端口
|
||||
|
||||
如果设置:
|
||||
|
||||
```bash
|
||||
export BEAVER_BASE_DOMAIN=203.0.113.10
|
||||
```
|
||||
|
||||
`deploy-control` 会把它识别成 IP,生成类似:
|
||||
|
||||
```text
|
||||
http://203.0.113.10:20037
|
||||
```
|
||||
|
||||
这是直连实例容器的宿主机端口模式,不是 `router-proxy` 的 Host 路由模式。要得到 `https://alice.apps.example.com` 这类地址,请改用真实域名并配置通配 DNS。
|
||||
|
||||
## 18. 重新部署基础容器
|
||||
|
||||
只重建基础容器和可选 sidecar:
|
||||
|
||||
Reference in New Issue
Block a user