184 lines
5.4 KiB
Markdown
184 lines
5.4 KiB
Markdown
# Beaver Project
|
||
|
||
`Beaver Project` 是一套单机 Docker 部署的多实例运行环境:
|
||
|
||
- 用户先进入独立的 `auth-portal` 完成注册或登录。
|
||
- 注册会触发 `authz-service` 调用 `deploy-control`。
|
||
- `deploy-control` 在同一台机器上创建一个独立的 `app-instance` 容器。
|
||
- `router-proxy` 按实例域名把流量转发到对应容器。
|
||
|
||
当前推荐的最小部署方式是一台 Linux / WSL2 Ubuntu 机器加 Docker。生产域名和 HTTPS 可以放在项目外层的 Nginx、Caddy、Traefik 或云负载均衡上。
|
||
|
||
## 组件
|
||
|
||
| 目录 | 职责 | 默认端口 |
|
||
| --- | --- | --- |
|
||
| `auth-portal/` | 用户登录、注册、模型配置引导入口 | `3081` |
|
||
| `authz-service/` | AuthZ 服务,负责账号和 backend 身份编排 | `19090` |
|
||
| `deploy-control/` | 部署控制面,调用 Docker 创建和管理实例 | `8090` |
|
||
| `router-proxy/` | 统一实例入口代理,按 Host 分发到实例容器 | `8088` |
|
||
| `app-instance/` | 单用户运行实例,容器内包含前端、后端和 Nginx | 容器内 `8080` |
|
||
|
||
公网环境通常只暴露:
|
||
|
||
- `auth-portal`: `3081`,或外层代理后的 `https://portal.example.com`
|
||
- `router-proxy`: `8088`,或外层代理后的 `https://<slug>.apps.example.com`
|
||
|
||
不要直接把 `deploy-control:8090` 和 `authz-service:19090` 暴露到公网。
|
||
|
||
## 请求链路
|
||
|
||
注册:
|
||
|
||
```text
|
||
Browser
|
||
-> auth-portal
|
||
-> authz-service POST /portal/register
|
||
-> deploy-control POST /api/instances/register
|
||
-> app-instance/create-instance.sh
|
||
-> app-instance POST /api/auth/register
|
||
-> authz-service /oauth/register or /backends/register
|
||
-> auth-portal provider onboarding
|
||
-> deploy-control POST /api/instances/configure-provider
|
||
```
|
||
|
||
登录:
|
||
|
||
```text
|
||
Browser
|
||
-> auth-portal
|
||
-> deploy-control POST /api/instances/resolve
|
||
-> app-instance POST /api/auth/login
|
||
-> app-instance frontend URL
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
本机完整流程见:
|
||
|
||
- [部署指南.md](./部署指南.md)
|
||
|
||
域名、HTTPS、公网反向代理说明见:
|
||
|
||
- [域名配置指引.md](./域名配置指引.md)
|
||
|
||
最小配置变量:
|
||
|
||
```bash
|
||
export PROJECT_ROOT=/home/ivan/xuan/beaver_project
|
||
export BEAVER_NET=beaver-instance-edge
|
||
export BEAVER_PROXY_CONTAINER_NAME=beaver-router-proxy
|
||
|
||
export BEAVER_DEPLOY_TOKEN="$(openssl rand -hex 32)"
|
||
export BEAVER_AUTHZ_INTERNAL_TOKEN="$(openssl rand -hex 32)"
|
||
|
||
export BEAVER_BASE_DOMAIN=localhost
|
||
export BEAVER_AUTHZ_URL='http://beaver-authz-service:19090'
|
||
export BEAVER_DEPLOY_URL='http://beaver-deploy-control:8090'
|
||
|
||
export BEAVER_OUTLOOK_MCP_URL=''
|
||
export BEAVER_OUTLOOK_MCP_SERVER_ID='outlook_mcp'
|
||
```
|
||
|
||
启动顺序:
|
||
|
||
1. 创建运行目录。
|
||
2. 构建四个镜像。
|
||
3. 创建共享 Docker network。
|
||
4. 启动 `router-proxy`。
|
||
5. 启动 `authz-service`。
|
||
6. 启动 `deploy-control`。
|
||
7. 启动 `auth-portal`。
|
||
8. 打开 `http://127.0.0.1:3081/register` 测试注册。
|
||
|
||
## 关键配置关系
|
||
|
||
`DEPLOY_API_TOKEN` 和 `DEPLOY_CONTROL_API_TOKEN` 必须相等:
|
||
|
||
- `auth-portal` / `authz-service` 用 `DEPLOY_API_TOKEN` 请求 `deploy-control`。
|
||
- `deploy-control` 用 `DEPLOY_CONTROL_API_TOKEN` 校验请求。
|
||
|
||
`AUTHZ_ISSUER` 在这套单机部署里要写容器网络地址:
|
||
|
||
```text
|
||
http://beaver-authz-service:19090
|
||
```
|
||
|
||
不要写成 `http://127.0.0.1:19090`,因为新创建的 `app-instance` 容器里的 `127.0.0.1` 指向它自己,不是 AuthZ 容器。
|
||
|
||
`DEPLOY_PUBLIC_*` 决定新实例展示给用户的 URL:
|
||
|
||
```bash
|
||
DEPLOY_PUBLIC_SCHEME=http
|
||
DEPLOY_PUBLIC_BASE_DOMAIN=localhost
|
||
DEPLOY_PUBLIC_PORT=8088
|
||
```
|
||
|
||
本机测试时实例 URL 形如:
|
||
|
||
```text
|
||
http://alice.localhost:8088
|
||
```
|
||
|
||
正式 HTTPS 域名通常改成:
|
||
|
||
```bash
|
||
DEPLOY_PUBLIC_SCHEME=https
|
||
DEPLOY_PUBLIC_BASE_DOMAIN=apps.example.com
|
||
DEPLOY_PUBLIC_PORT=443
|
||
```
|
||
|
||
实例 URL 形如:
|
||
|
||
```text
|
||
https://alice.apps.example.com
|
||
```
|
||
|
||
前提是你已经在项目外层把 `*.apps.example.com` 的 `80/443` 流量转发到 `router-proxy:8088`。
|
||
|
||
## 模型配置方式
|
||
|
||
当前版本不会在注册创建实例时写入模型 provider、model 或 API key。
|
||
|
||
流程是:
|
||
|
||
1. 注册先创建一个不含模型凭证的实例。
|
||
2. `auth-portal` 进入模型配置引导页。
|
||
3. 用户确认后,Portal 调用 `deploy-control /api/instances/configure-provider`。
|
||
4. `deploy-control` 写入该实例的 `config.json` 并重启对应容器。
|
||
|
||
如果用户跳过引导,实例仍会创建成功,但后续需要在实例内补齐 provider 配置后才能正常调用模型。
|
||
|
||
## 持久化目录
|
||
|
||
至少保留:
|
||
|
||
```text
|
||
authz-service/runtime/data
|
||
app-instance/runtime/instances
|
||
app-instance/runtime/registry
|
||
router-proxy/runtime/conf.d
|
||
```
|
||
|
||
不要在需要保留账号、实例或配置时删除这些目录。
|
||
|
||
## 模板文件
|
||
|
||
可参考这些环境变量模板:
|
||
|
||
- [`.env.example`](./.env.example)
|
||
- [`auth-portal/src/.env.example`](./auth-portal/src/.env.example)
|
||
- [`authz-service/.env.example`](./authz-service/.env.example)
|
||
- [`deploy-control/.env.example`](./deploy-control/.env.example)
|
||
- [`router-proxy/.env.example`](./router-proxy/.env.example)
|
||
|
||
这些模板不会被脚本自动加载。你可以手动 `export`,也可以在 `docker run` 时使用 `--env-file`。
|
||
|
||
## 子项目文档
|
||
|
||
- [`app-instance/README.md`](./app-instance/README.md)
|
||
- [`auth-portal/src/README.md`](./auth-portal/src/README.md)
|
||
- [`authz-service/README.md`](./authz-service/README.md)
|
||
- [`deploy-control/README.md`](./deploy-control/README.md)
|
||
- [`router-proxy/README.md`](./router-proxy/README.md)
|