Refactor app instance to Keycloak SSO
This commit is contained in:
@ -1,120 +1,56 @@
|
||||
# app-instance
|
||||
|
||||
单实例应用单元:
|
||||
|
||||
- 一个 Docker 容器里同时运行前端、后端和 Nginx 反代
|
||||
- 前端走 `/`
|
||||
- 后端 API 走 `/api`
|
||||
- WebSocket 走 `/ws`
|
||||
单体 app instance:一个 Docker 容器内运行前端、后端和 Nginx。这个目录只提供干净的应用实例,不再负责用户注册登录、实例编排、注册表或反向代理路由。
|
||||
|
||||
## 关键文件
|
||||
|
||||
- `Dockerfile`
|
||||
- 统一镜像构建入口
|
||||
- `entrypoint.sh`
|
||||
- 容器内启动前端、后端、Nginx
|
||||
- `create-instance.sh`
|
||||
- 创建实例目录、生成配置、启动容器、写注册表
|
||||
- `remove-instance.sh`
|
||||
- 删除容器、移除注册表、可选清理实例目录
|
||||
- `list-instances.sh`
|
||||
- 查看当前注册实例
|
||||
- `instance-registry.py`
|
||||
- 维护 `runtime/registry/instances.json`
|
||||
- `Dockerfile`: 统一镜像构建入口
|
||||
- `entrypoint.sh`: 容器内启动前端、后端、Nginx
|
||||
- `run-standalone.sh`: 从 `.env` 读取参数,构建并运行单体容器
|
||||
- `.env.example`: 可复制的部署参数模板
|
||||
|
||||
## 注册表
|
||||
## Keycloak SSO
|
||||
|
||||
默认注册表路径:
|
||||
当前登录交给 Keycloak:
|
||||
|
||||
- issuer: `https://keycloak.bwgdi.com/realms/beaver`
|
||||
- client_id: `beaver-agnet`
|
||||
- flow: Authorization Code + PKCE S256
|
||||
- password grant: disabled
|
||||
- client secret: none
|
||||
|
||||
应用需要在 Keycloak client 中配置:
|
||||
|
||||
- `redirect_uri`: `http://<host-ip>:<host-port>/auth/callback`
|
||||
- `post_logout_redirect_uri`: `http://<host-ip>:<host-port>/logout/callback`
|
||||
- `web_origin`: `http://<host-ip>:<host-port>`
|
||||
|
||||
默认单机部署示例:
|
||||
|
||||
```text
|
||||
runtime/registry/instances.json
|
||||
redirect_uri: http://172.19.0.245:18080/auth/callback
|
||||
post_logout_redirect_uri: http://172.19.0.245:18080/logout/callback
|
||||
web_origin: http://172.19.0.245:18080
|
||||
```
|
||||
|
||||
每条记录至少包含:
|
||||
|
||||
- `instance_id`
|
||||
- `instance_slug`
|
||||
- `container_name`
|
||||
- `host_port`
|
||||
- `public_url`
|
||||
- `instance_root`
|
||||
- `image_name`
|
||||
|
||||
## 常用命令
|
||||
|
||||
### 1. 构建镜像
|
||||
## 部署
|
||||
|
||||
```bash
|
||||
docker build -t beaver/app-instance:latest .
|
||||
cp .env.example .env
|
||||
./run-standalone.sh --build --replace
|
||||
```
|
||||
|
||||
### 2. 创建实例
|
||||
脚本会输出当前需要填到 Keycloak 的 `redirect_uri`、`post_logout_redirect_uri` 和 `web_origin`。
|
||||
|
||||
```bash
|
||||
./create-instance.sh \
|
||||
--image beaver/app-instance:latest \
|
||||
--instance-id demo-001 \
|
||||
--auth-username admin \
|
||||
--auth-password 123456 \
|
||||
--api-key 'your-api-key'
|
||||
```
|
||||
## 数据目录
|
||||
|
||||
可选参数:
|
||||
|
||||
- `--host-port`
|
||||
- `--public-url`
|
||||
- `--username`
|
||||
- `--email`
|
||||
- `--instance-host`
|
||||
- `--authz-base-url`
|
||||
- `--backend-id`
|
||||
- `--client-id`
|
||||
- `--client-secret`
|
||||
- `--network`
|
||||
- `--host-bind-ip`
|
||||
- `--initial-skills-dir`
|
||||
- `--skip-initial-skills`
|
||||
- `--build`
|
||||
- `--replace`
|
||||
|
||||
### 3. 查看实例
|
||||
|
||||
```bash
|
||||
./list-instances.sh
|
||||
./list-instances.sh --json
|
||||
```
|
||||
|
||||
### 4. 删除实例
|
||||
|
||||
```bash
|
||||
./remove-instance.sh --instance-id demo-001
|
||||
```
|
||||
|
||||
如果要把实例目录也一并清掉:
|
||||
|
||||
```bash
|
||||
./remove-instance.sh --instance-id demo-001 --purge-data
|
||||
```
|
||||
|
||||
## 目录约定
|
||||
|
||||
默认实例数据目录:
|
||||
默认数据目录:
|
||||
|
||||
```text
|
||||
runtime/instances/<instance-slug>/
|
||||
runtime/standalone/beaver-home/
|
||||
```
|
||||
|
||||
其中会生成:
|
||||
|
||||
```text
|
||||
runtime/instances/<instance-slug>/
|
||||
└── beaver-home
|
||||
├── config.json
|
||||
├── web_auth_users.json
|
||||
└── workspace/
|
||||
```
|
||||
|
||||
这个目录是单用户 sandbox 的配置与数据边界。容器内会把它挂到:
|
||||
容器内挂载到:
|
||||
|
||||
```text
|
||||
/root/.beaver/
|
||||
@ -127,36 +63,4 @@ BEAVER_CONFIG_PATH=/root/.beaver/config.json
|
||||
BEAVER_WORKSPACE=/root/.beaver/workspace
|
||||
```
|
||||
|
||||
所以模型 `provider/api_key/api_base/model` 配一次即可,Web / channel 请求不需要、也不应该携带 API Key。
|
||||
|
||||
`create-instance.sh` 默认会把仓库根目录的 `skills/` 非覆盖式复制到实例 workspace,并把同一个目录只读挂载到实例容器的 `/opt/app/initial-skills`。`entrypoint.sh` 每次启动都会用该目录补齐缺失的 published 初始 skills;已有 skill 目录不会被覆盖,index 只做并集追加。
|
||||
|
||||
## 当前状态
|
||||
|
||||
这层已经支持:
|
||||
|
||||
- 统一镜像构建
|
||||
- 镜像内安装并启动新的 `beaver` 后端
|
||||
- 实例创建
|
||||
- 实例删除
|
||||
- 实例列表
|
||||
- 基于注册表的端口分配
|
||||
- 为 deploy-control / router-proxy 记录用户名和实例 host
|
||||
|
||||
## 生产注意
|
||||
|
||||
- 实例容器的宿主机端口默认只绑定 `127.0.0.1`
|
||||
- 外部访问应统一走 `router-proxy`
|
||||
- 如果你确实要把单个实例端口直接暴露到公网,再显式传 `--host-bind-ip 0.0.0.0`
|
||||
- 使用共享 `external-connector` sidecar 时,每个实例容器都必须带自己的内部回调地址:
|
||||
`EXTERNAL_CONNECTOR_CALLBACK_BASE_URL=http://<app-instance-container-name>:8080`
|
||||
- 通过 `create-instance.sh --network <docker-network>` 创建实例时,脚本会默认使用
|
||||
`http://<container-name>:8080` 作为回调地址;生产部署也可以用
|
||||
`--external-connector-callback-base-url <url>` 显式覆盖
|
||||
- `BEAVER_BRIDGE_BASE_URL` 只作为 sidecar 的旧连接或兜底地址;多实例部署不能依赖它路由所有入站事件
|
||||
|
||||
下一步可以继续接:
|
||||
|
||||
- portal 调用创建实例
|
||||
- URL 分配和反向代理
|
||||
- 实例续期 / 停用 / 启用
|
||||
模型 provider、API key、workspace 数据都在这个目录下维护。
|
||||
|
||||
Reference in New Issue
Block a user