# deploy-control

部署机接口：

- 给 `auth-portal` 提供实例创建和实例解析 API
- 调用 `app-instance/create-instance.sh`
- 在实例创建后刷新 `router-proxy`

## 接口

- `GET /healthz`
- `POST /api/instances/register`
- `POST /api/instances/resolve`
- `POST /api/instances/configure-provider`
- `DELETE /api/instances/{instance_id}`

## 关键环境变量

- `DEPLOY_CONTROL_API_TOKEN`
- `DEFAULT_AUTHZ_BASE_URL`
- `DEFAULT_AUTHZ_OUTLOOK_MCP_URL`
- `DEFAULT_OUTLOOK_MCP_SERVER_ID`
- `DEFAULT_OUTLOOK_MCP_CALL_TIMEOUT_SECONDS`
- `DEPLOY_PUBLIC_BASE_DOMAIN`
- `DEPLOY_PUBLIC_PORT`
- `DEPLOY_PUBLIC_SCHEME`
- `APP_INSTANCE_NETWORK_NAME`

建议直接参考：

- [`.env.example`](/home/ivan/xuan/beaver_project/deploy-control/.env.example)

默认实例 URL 形如：

```text
http://<instance-slug>.localhost:8088
```

实例容器本身的 `20000-29999` 端口默认只绑定到部署机 `127.0.0.1`，外部入口应走 `router-proxy`。

如果你希望所有新实例默认带 Outlook MCP HTTP 工具，可以设置：

```bash
DEFAULT_AUTHZ_OUTLOOK_MCP_URL=http://10.6.80.29:8000/mcp
DEFAULT_OUTLOOK_MCP_SERVER_ID=outlook_mcp
DEFAULT_OUTLOOK_MCP_CALL_TIMEOUT_SECONDS=60
```

这样 `deploy-control` 创建的新实例会自动写入一条默认 MCP server 配置，并默认使用 `oauth_backend_token` + `mcp:<server_id>` 的 audience。

## 本机启动

```bash
cd /home/ivan/xuan/beaver_project/deploy-control
uv run server.py
```

## Docker 启动

如果要容器化运行，需要挂载：

- Docker socket：`/var/run/docker.sock`
- `/home/ivan/xuan/beaver_project/app-instance`
- `/home/ivan/xuan/beaver_project/router-proxy`
- `/home/ivan/xuan/beaver_project/skills`

并传入对应环境变量，让容器内脚本路径仍能访问这些目录。

关键点：

- 宿主机路径要原样挂进容器，不要改挂载目标路径
- 同时显式传 `APP_INSTANCE_DIR` 和 `ROUTER_PROXY_DIR`

示例：

```bash
docker run -d \
  --name beaver-deploy-control \
  --restart unless-stopped \
  --network beaver-instance-edge \
  -p 8090:8090 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /home/ivan/xuan/beaver_project/app-instance:/home/ivan/xuan/beaver_project/app-instance \
  -v /home/ivan/xuan/beaver_project/router-proxy:/home/ivan/xuan/beaver_project/router-proxy \
  -v /home/ivan/xuan/beaver_project/skills:/home/ivan/xuan/beaver_project/skills:ro \
  -e APP_INSTANCE_DIR=/home/ivan/xuan/beaver_project/app-instance \
  -e ROUTER_PROXY_DIR=/home/ivan/xuan/beaver_project/router-proxy \
  -e DEFAULT_INITIAL_SKILLS_DIR=/home/ivan/xuan/beaver_project/skills \
  -e DEPLOY_CONTROL_API_TOKEN=change-me \
  -e APP_INSTANCE_IMAGE=beaver/app-instance:latest \
  -e APP_INSTANCE_NETWORK_NAME=beaver-instance-edge \
  beaver/deploy-control:latest
```

如果这里错把宿主机目录映射成容器内的另一个短路径，例如 `/app-instance`，那么 `deploy-control` 通过 Docker socket 创建实例时会把错误路径传给 Docker，最终导致实例容器拿不到 `config.json` 并持续重启。`skills` 目录也必须挂载到同一个绝对路径；否则新实例第一次创建时不会在 workspace 里种入初始 skills。

新实例注册时不会写入模型 provider/API key。注册后由 `auth-portal` 引导页调用 `POST /api/instances/configure-provider`，在用户确认后写入该实例配置并重启实例容器。
