docs(README): 更新项目部署文档添加完整部署指南
更新 README.md 文件,提供详细的单机部署指南,包括: - 完整的服务架构说明和请求链路图解 - 环境变量配置说明和示例 - 逐步部署流程(镜像构建、网络创建、服务启动) - 健康检查和首次注册验收步骤 - 常见问题解答 同时更新各个子模块的 README 添加环境变量示例文件引用
This commit is contained in:
21
.env.example
Normal file
21
.env.example
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Shared values used by the root deployment flow in README.md
|
||||||
|
|
||||||
|
PROJECT_ROOT=/home/ivan/xuan/nano_project
|
||||||
|
NANO_NET=nano-instance-edge
|
||||||
|
|
||||||
|
NANO_DEPLOY_TOKEN=change-me
|
||||||
|
NANO_AUTHZ_INTERNAL_TOKEN=change-me
|
||||||
|
|
||||||
|
NANO_SERVER_IP=203.0.113.10
|
||||||
|
NANO_BASE_DOMAIN=203.0.113.10.nip.io
|
||||||
|
|
||||||
|
NANO_PROVIDER=openai
|
||||||
|
NANO_MODEL=openai/gpt-5
|
||||||
|
NANO_API_KEY=sk-xxxxxxxx
|
||||||
|
NANO_API_BASE=
|
||||||
|
|
||||||
|
# Must be reachable from app-instance containers.
|
||||||
|
NANO_AUTHZ_URL=http://nano-authz-service:19090
|
||||||
|
|
||||||
|
# Must be reachable from auth-portal and authz-service containers.
|
||||||
|
NANO_DEPLOY_URL=http://nano-deploy-control:8090
|
||||||
465
README.md
465
README.md
@ -1,108 +1,395 @@
|
|||||||
# nano_project
|
# nano_project
|
||||||
|
|
||||||
按当前部署模型整理后的顶层目录:
|
单机部署版运行结构:
|
||||||
|
|
||||||
- `app-instance/`
|
- `auth-portal`
|
||||||
- 单用户实例容器。
|
- 用户入口页,提供登录、注册、跳转。
|
||||||
- 一个容器里同时包含前端和后端。
|
- `authz-service`
|
||||||
- `backend/` 来自 `nanobot-backend`
|
- AuthZ 服务。
|
||||||
- `frontend/` 来自 `nanobot-fronted`
|
- 现在负责注册编排:`auth-portal -> authz-service -> deploy-control -> app-instance -> authz-service`
|
||||||
- 已包含统一 Dockerfile、启动脚本和实例管理脚本。
|
- `deploy-control`
|
||||||
- `authz-service/`
|
- 部署机控制面。
|
||||||
- 鉴权服务容器。
|
- 负责创建实例、解析实例、刷新反向代理。
|
||||||
- `src/` 来自 `Authz-service`
|
- `router-proxy`
|
||||||
- 已包含 Dockerfile、启动脚本和空白种子数据。
|
- 统一入口代理。
|
||||||
- `auth-portal/`
|
- 按 Host 把 `<slug>.<base_domain>` 转发到对应实例容器。
|
||||||
- 登录 / 注册 / 跳转入口容器。
|
- `app-instance`
|
||||||
- `src/` 来自 `nanobot-auth-portal`
|
- 真正的单用户实例。
|
||||||
- `runtime/` 预留给后续启动脚本和环境配置。
|
- 一个容器里同时包含前端、后端和 Nginx。
|
||||||
- `deploy-control/`
|
|
||||||
- 部署机接口容器。
|
|
||||||
- 负责创建实例、解析实例路由、刷新反向代理。
|
|
||||||
- `router-proxy/`
|
|
||||||
- 专属 URL 到实例容器的反向代理容器。
|
|
||||||
- 按 Host 路由到对应 `app-instance`。
|
|
||||||
|
|
||||||
## 说明
|
## 请求链路
|
||||||
|
|
||||||
这里的代码目录现在是实际副本,不再依赖符号链接。
|
注册:
|
||||||
|
|
||||||
原始来源是:
|
```text
|
||||||
|
Browser
|
||||||
|
-> auth-portal
|
||||||
|
-> authz-service POST /portal/register
|
||||||
|
-> deploy-control POST /api/instances/register
|
||||||
|
-> create-instance.sh
|
||||||
|
-> app-instance POST /api/auth/register
|
||||||
|
-> authz-service /oauth/register or /backends/register
|
||||||
|
```
|
||||||
|
|
||||||
- `/home/ivan/xuan/nano_project/app-instance/backend` 来自 `/home/ivan/xuan/steven_project/nanobot-backend`
|
登录:
|
||||||
- `/home/ivan/xuan/nano_project/app-instance/frontend` 来自 `/home/ivan/xuan/steven_project/nanobot-fronted`
|
|
||||||
- `/home/ivan/xuan/nano_project/authz-service/src` 来自 `/home/ivan/xuan/steven_project/Authz-service`
|
|
||||||
- `/home/ivan/xuan/nano_project/auth-portal/src` 来自 `/home/ivan/xuan/steven_project/nanobot-auth-portal`
|
|
||||||
|
|
||||||
之后你在 `nano_project` 里继续改代码,不会再联动改到原仓库。
|
```text
|
||||||
|
Browser
|
||||||
|
-> auth-portal
|
||||||
|
-> deploy-control POST /api/instances/resolve
|
||||||
|
-> app-instance POST /api/auth/login
|
||||||
|
```
|
||||||
|
|
||||||
## 本次复制排除项
|
## 这份部署指南的前提
|
||||||
|
|
||||||
为避免把本地依赖和构建垃圾一起带过来,这次复制排除了这些内容:
|
这份 README 只覆盖一套基准方案:
|
||||||
|
|
||||||
- `.git/`
|
- 一台 Linux 服务器
|
||||||
- `.venv/`
|
- 用 Docker 运行 `auth-portal`、`authz-service`、`deploy-control`、`router-proxy`
|
||||||
- `node_modules/`
|
- `deploy-control` 通过 Docker socket 在同一台机器上创建 `app-instance`
|
||||||
- `.next/`
|
- 所有容器共用一个 Docker network:`nano-instance-edge`
|
||||||
- `.next-dev/`
|
- 测试域名先用 `nip.io`
|
||||||
- `.pytest_cache/`
|
|
||||||
- `.ruff_cache/`
|
|
||||||
- `__pycache__/`
|
|
||||||
- `dist/`
|
|
||||||
- `build/`
|
|
||||||
- `*.pyc`
|
|
||||||
- `tsconfig.tsbuildinfo`
|
|
||||||
- `.env`
|
|
||||||
- `.env.local`
|
|
||||||
|
|
||||||
## 当前结构
|
如果你后面要接 HTTPS、外部 LB、Kubernetes、真实 DNS,这份流程仍然适合作为最小可运行基线。
|
||||||
|
|
||||||
|
可直接参考这些模板文件:
|
||||||
|
|
||||||
|
- [`.env.example`](/home/ivan/xuan/nano_project/.env.example)
|
||||||
|
- [`auth-portal/src/.env.example`](/home/ivan/xuan/nano_project/auth-portal/src/.env.example)
|
||||||
|
- [`authz-service/.env.example`](/home/ivan/xuan/nano_project/authz-service/.env.example)
|
||||||
|
- [`deploy-control/.env.example`](/home/ivan/xuan/nano_project/deploy-control/.env.example)
|
||||||
|
- [`router-proxy/.env.example`](/home/ivan/xuan/nano_project/router-proxy/.env.example)
|
||||||
|
|
||||||
|
注意:
|
||||||
|
|
||||||
|
- 这些文件是模板,不会被现有脚本自动加载
|
||||||
|
- 你可以手动 `export`,或者在 `docker run` 时使用 `--env-file`
|
||||||
|
|
||||||
|
## 部署前必须先定好的值
|
||||||
|
|
||||||
|
先准备这些值:
|
||||||
|
|
||||||
|
- `PROJECT_ROOT`
|
||||||
|
- 仓库根目录。
|
||||||
|
- `NANO_NET`
|
||||||
|
- Docker network 名。
|
||||||
|
- 推荐固定成 `nano-instance-edge`。
|
||||||
|
- `NANO_DEPLOY_TOKEN`
|
||||||
|
- `auth-portal` / `authz-service` 调 `deploy-control` 时用的 Bearer token。
|
||||||
|
- `NANO_AUTHZ_INTERNAL_TOKEN`
|
||||||
|
- AuthZ 内部接口 token。
|
||||||
|
- `NANO_SERVER_IP`
|
||||||
|
- 服务器公网 IP,供 `nip.io` 测试使用。
|
||||||
|
- `NANO_BASE_DOMAIN`
|
||||||
|
- 实例基域名。
|
||||||
|
- 测试环境推荐 `<SERVER_IP>.nip.io`
|
||||||
|
- `NANO_PROVIDER`
|
||||||
|
- 默认 provider,例如 `openai`
|
||||||
|
- `NANO_MODEL`
|
||||||
|
- 默认模型,例如 `openai/gpt-5`
|
||||||
|
- `NANO_API_KEY`
|
||||||
|
- 默认分发给新实例的 provider API key
|
||||||
|
- `NANO_API_BASE`
|
||||||
|
- 可空,自定义 provider base URL
|
||||||
|
- `NANO_AUTHZ_URL`
|
||||||
|
- 这个值必须是 `app-instance` 容器能访问到的 AuthZ 地址
|
||||||
|
- `NANO_DEPLOY_URL`
|
||||||
|
- `auth-portal` 和 `authz-service` 在容器网络里访问 deploy-control 的地址
|
||||||
|
|
||||||
|
直接导出一套最小配置:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PROJECT_ROOT=/home/ivan/xuan/nano_project
|
||||||
|
export NANO_NET=nano-instance-edge
|
||||||
|
|
||||||
|
export NANO_DEPLOY_TOKEN="$(openssl rand -hex 32)"
|
||||||
|
export NANO_AUTHZ_INTERNAL_TOKEN="$(openssl rand -hex 32)"
|
||||||
|
|
||||||
|
export NANO_SERVER_IP=203.0.113.10
|
||||||
|
export NANO_BASE_DOMAIN="${NANO_SERVER_IP}.nip.io"
|
||||||
|
|
||||||
|
export NANO_PROVIDER=openai
|
||||||
|
export NANO_MODEL=openai/gpt-5
|
||||||
|
export NANO_API_KEY='sk-xxxxxxxx'
|
||||||
|
export NANO_API_BASE=''
|
||||||
|
|
||||||
|
export NANO_AUTHZ_URL='http://nano-authz-service:19090'
|
||||||
|
export NANO_DEPLOY_URL='http://nano-deploy-control:8090'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 变量到底是什么
|
||||||
|
|
||||||
|
最容易混淆的是下面这几组:
|
||||||
|
|
||||||
|
- `DEPLOY_API_TOKEN`
|
||||||
|
- 调用方带出去的 token。
|
||||||
|
- `auth-portal` 和 `authz-service` 会用它请求 `deploy-control`。
|
||||||
|
- `DEPLOY_CONTROL_API_TOKEN`
|
||||||
|
- `deploy-control` 服务端校验的 token。
|
||||||
|
- 它必须和 `DEPLOY_API_TOKEN` 相等。
|
||||||
|
- `AUTHZ_ISSUER`
|
||||||
|
- 当前实现里它既是 AuthZ 的 issuer,也是新实例要访问的 AuthZ base URL。
|
||||||
|
- 所以不要乱写 `127.0.0.1`,要写成实例容器能访问到的地址。
|
||||||
|
- `APP_INSTANCE_PROVIDER`
|
||||||
|
- 新实例默认 provider。
|
||||||
|
- `APP_INSTANCE_MODEL`
|
||||||
|
- 新实例默认模型。
|
||||||
|
- `APP_INSTANCE_API_KEY`
|
||||||
|
- 新实例默认 API key。
|
||||||
|
- `APP_INSTANCE_API_BASE`
|
||||||
|
- 新实例默认 API base。
|
||||||
|
- `DEFAULT_AUTHZ_BASE_URL`
|
||||||
|
- `deploy-control` 在没收到显式 `authz_base_url` 时,给新实例写入的兜底 AuthZ 地址。
|
||||||
|
|
||||||
|
当前版本里,provider 配置不是从 AuthZ setting 下发的。
|
||||||
|
它是在创建实例时由 `deploy-control` 写入 `app-instance` 的 `config.json`。
|
||||||
|
|
||||||
|
## 目录持久化
|
||||||
|
|
||||||
|
至少保留这几个目录:
|
||||||
|
|
||||||
|
- `authz-service/runtime/data`
|
||||||
|
- `app-instance/runtime`
|
||||||
|
- `router-proxy/runtime`
|
||||||
|
|
||||||
|
建议先创建:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p \
|
||||||
|
"$PROJECT_ROOT/authz-service/runtime/data" \
|
||||||
|
"$PROJECT_ROOT/app-instance/runtime/instances" \
|
||||||
|
"$PROJECT_ROOT/app-instance/runtime/registry" \
|
||||||
|
"$PROJECT_ROOT/router-proxy/runtime/conf.d"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1. 构建镜像
|
||||||
|
|
||||||
|
先把四个镜像都构建好。虽然 `deploy-control` 在镜像缺失时也能触发构建,但上线前先显式构建更容易排错。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
docker build -t nano/app-instance:latest app-instance
|
||||||
|
docker build -t nano/authz-service:latest authz-service
|
||||||
|
docker build -t nano/deploy-control:latest deploy-control
|
||||||
|
docker build -t nano/auth-portal:latest auth-portal/src
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. 创建共享网络
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker network inspect "$NANO_NET" >/dev/null 2>&1 || docker network create "$NANO_NET"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 启动 router-proxy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
PROXY_NETWORK_NAME="$NANO_NET" \
|
||||||
|
PROXY_HTTP_PORT=8088 \
|
||||||
|
./router-proxy/start-proxy.sh --replace
|
||||||
|
```
|
||||||
|
|
||||||
|
默认对外入口:
|
||||||
|
|
||||||
|
- `router-proxy`: `http://<slug>.<base_domain>:8088`
|
||||||
|
|
||||||
|
## 4. 启动 authz-service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker rm -f nano-authz-service >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
docker run -d \
|
||||||
|
--name nano-authz-service \
|
||||||
|
--restart unless-stopped \
|
||||||
|
--network "$NANO_NET" \
|
||||||
|
-p 19090:19090 \
|
||||||
|
-v "$PROJECT_ROOT/authz-service/runtime/data:/var/lib/authz-service/data" \
|
||||||
|
-e AUTHZ_ISSUER="$NANO_AUTHZ_URL" \
|
||||||
|
-e AUTHZ_INTERNAL_TOKEN="$NANO_AUTHZ_INTERNAL_TOKEN" \
|
||||||
|
-e DEPLOY_API_BASE_URL="$NANO_DEPLOY_URL" \
|
||||||
|
-e DEPLOY_API_TOKEN="$NANO_DEPLOY_TOKEN" \
|
||||||
|
nano/authz-service:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
这里最重要的是:
|
||||||
|
|
||||||
|
- `AUTHZ_ISSUER` 现在不能只按“外部访问地址”理解
|
||||||
|
- 它必须是后续 `app-instance` 容器也能访问到的地址
|
||||||
|
- 这套单机 Docker 方案里直接用 `http://nano-authz-service:19090`
|
||||||
|
|
||||||
|
## 5. 启动 deploy-control
|
||||||
|
|
||||||
|
`deploy-control` 需要高权限:
|
||||||
|
|
||||||
|
- 读写 Docker socket
|
||||||
|
- 访问 `app-instance/`
|
||||||
|
- 访问 `router-proxy/`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker rm -f nano-deploy-control >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
docker run -d \
|
||||||
|
--name nano-deploy-control \
|
||||||
|
--restart unless-stopped \
|
||||||
|
--network "$NANO_NET" \
|
||||||
|
-p 8090:8090 \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-v "$PROJECT_ROOT/app-instance:/app-instance" \
|
||||||
|
-v "$PROJECT_ROOT/router-proxy:/router-proxy" \
|
||||||
|
-e DEPLOY_CONTROL_API_TOKEN="$NANO_DEPLOY_TOKEN" \
|
||||||
|
-e APP_INSTANCE_IMAGE="nano/app-instance:latest" \
|
||||||
|
-e APP_INSTANCE_NETWORK_NAME="$NANO_NET" \
|
||||||
|
-e APP_INSTANCE_PROVIDER="$NANO_PROVIDER" \
|
||||||
|
-e APP_INSTANCE_MODEL="$NANO_MODEL" \
|
||||||
|
-e APP_INSTANCE_API_KEY="$NANO_API_KEY" \
|
||||||
|
-e APP_INSTANCE_API_BASE="$NANO_API_BASE" \
|
||||||
|
-e DEFAULT_AUTHZ_BASE_URL="$NANO_AUTHZ_URL" \
|
||||||
|
-e DEPLOY_PUBLIC_SCHEME="http" \
|
||||||
|
-e DEPLOY_PUBLIC_BASE_DOMAIN="$NANO_BASE_DOMAIN" \
|
||||||
|
-e DEPLOY_PUBLIC_PORT="8088" \
|
||||||
|
-e DEPLOY_AUTO_START_PROXY="1" \
|
||||||
|
nano/deploy-control:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
当前版本里,新实例的默认大模型配置就是从这里分发的:
|
||||||
|
|
||||||
|
- `APP_INSTANCE_PROVIDER`
|
||||||
|
- `APP_INSTANCE_MODEL`
|
||||||
|
- `APP_INSTANCE_API_KEY`
|
||||||
|
- `APP_INSTANCE_API_BASE`
|
||||||
|
|
||||||
|
如果 `APP_INSTANCE_API_KEY` 没配,新用户注册时创建实例会直接失败。
|
||||||
|
|
||||||
|
## 6. 启动 auth-portal
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker rm -f nano-auth-portal >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
docker run -d \
|
||||||
|
--name nano-auth-portal \
|
||||||
|
--restart unless-stopped \
|
||||||
|
--network "$NANO_NET" \
|
||||||
|
-p 3081:3081 \
|
||||||
|
-e AUTHZ_API_BASE_URL="$NANO_AUTHZ_URL" \
|
||||||
|
-e DEPLOY_API_BASE_URL="$NANO_DEPLOY_URL" \
|
||||||
|
-e DEPLOY_API_TOKEN="$NANO_DEPLOY_TOKEN" \
|
||||||
|
nano/auth-portal:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
当前页面入口:
|
||||||
|
|
||||||
|
- `http://<server-ip>:3081`
|
||||||
|
|
||||||
|
## 7. 上线前健康检查
|
||||||
|
|
||||||
|
先确认四个基础组件都起来了:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:19090/healthz
|
||||||
|
curl http://127.0.0.1:8090/healthz
|
||||||
|
curl -I http://127.0.0.1:3081
|
||||||
|
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
再确认 `router-proxy` 在跑:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs --tail=50 nano-router-proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. 首次注册验收
|
||||||
|
|
||||||
|
打开:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://<server-ip>:3081/register
|
||||||
|
```
|
||||||
|
|
||||||
|
注册一个新用户后,预期结果是:
|
||||||
|
|
||||||
|
1. `auth-portal` 调 `authz-service /portal/register`
|
||||||
|
2. `authz-service` 调 `deploy-control /api/instances/register`
|
||||||
|
3. `deploy-control` 创建一个新的 `app-instance`
|
||||||
|
4. `app-instance` 回调 AuthZ 完成 backend 身份初始化
|
||||||
|
5. 浏览器被跳转到该实例自己的 URL
|
||||||
|
|
||||||
|
同时你应该能看到:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
./app-instance/list-instances.sh --json
|
||||||
|
```
|
||||||
|
|
||||||
|
新实例 URL 形如:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://<instance-slug>.<base-domain>:8088
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你前面用的是:
|
||||||
|
|
||||||
|
```text
|
||||||
|
NANO_BASE_DOMAIN=<server-ip>.nip.io
|
||||||
|
```
|
||||||
|
|
||||||
|
那么实例地址会像:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://alice.203.0.113.10.nip.io:8088
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9. 常见问题
|
||||||
|
|
||||||
|
### 1. 为什么不要把 `AUTHZ_ISSUER` 写成 `http://127.0.0.1:19090`
|
||||||
|
|
||||||
|
因为 `app-instance` 容器里访问 `127.0.0.1` 只会打到它自己,不会打到 AuthZ 容器。
|
||||||
|
在当前实现里,`AUTHZ_ISSUER` 会被直接传给新实例当作 `authz_base_url`。
|
||||||
|
|
||||||
|
### 2. `DEPLOY_API_TOKEN` 和 `DEPLOY_CONTROL_API_TOKEN` 为什么要一样
|
||||||
|
|
||||||
|
因为一个是客户端发出去的 token,一个是服务端拿来校验的 token。
|
||||||
|
|
||||||
|
### 3. 这些 provider 配置是写到哪里
|
||||||
|
|
||||||
|
写到每个实例自己的:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app-instance/runtime/instances/<slug>/nanobot-home/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
不是写在 AuthZ 的某个 setting 里。
|
||||||
|
|
||||||
|
### 4. 现在支持每个用户注册时填自己的 API key 吗
|
||||||
|
|
||||||
|
后端请求模型已经支持 `provider/model/api_key/api_base` 字段,但当前 `auth-portal` 页面没有把这些字段暴露出来。
|
||||||
|
当前上线流程默认是:所有新实例先继承 `deploy-control` 上配置的默认 provider 凭证。
|
||||||
|
|
||||||
|
### 5. 现在内置 HTTPS 吗
|
||||||
|
|
||||||
|
没有。
|
||||||
|
当前内置 `router-proxy` 是 HTTP 入口。如果你要公网 HTTPS:
|
||||||
|
|
||||||
|
- 在外面再放一层 Nginx / Caddy / LB 做 TLS 终止
|
||||||
|
- 再把流量转给 `router-proxy:8088` 和 `auth-portal:3081`
|
||||||
|
|
||||||
|
## 10. 仓库结构
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/home/ivan/xuan/nano_project
|
/home/ivan/xuan/nano_project
|
||||||
├── README.md
|
├── README.md
|
||||||
├── app-instance
|
├── app-instance/
|
||||||
│ ├── backend/
|
├── auth-portal/
|
||||||
│ ├── frontend/
|
├── authz-service/
|
||||||
│ └── runtime/
|
├── deploy-control/
|
||||||
├── deploy-control
|
└── router-proxy/
|
||||||
│ ├── Dockerfile
|
|
||||||
│ └── server.py
|
|
||||||
├── router-proxy
|
|
||||||
│ ├── runtime/
|
|
||||||
│ ├── nginx.conf
|
|
||||||
│ └── render-routes.py
|
|
||||||
├── authz-service
|
|
||||||
│ ├── src/
|
|
||||||
│ ├── runtime/
|
|
||||||
│ └── Dockerfile
|
|
||||||
└── auth-portal
|
|
||||||
├── src/
|
|
||||||
└── runtime/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## app-instance 当前可用能力
|
各子目录更细的实现说明见:
|
||||||
|
|
||||||
`/home/ivan/xuan/nano_project/app-instance` 现在已经具备:
|
- [`app-instance/README.md`](/home/ivan/xuan/nano_project/app-instance/README.md)
|
||||||
|
- [`auth-portal/src/README.md`](/home/ivan/xuan/nano_project/auth-portal/src/README.md)
|
||||||
- 统一镜像构建:`Dockerfile`
|
- [`authz-service/README.md`](/home/ivan/xuan/nano_project/authz-service/README.md)
|
||||||
- 容器内启动前端、后端、Nginx:`entrypoint.sh`
|
- [`deploy-control/README.md`](/home/ivan/xuan/nano_project/deploy-control/README.md)
|
||||||
- 创建实例并写配置、起容器、登记注册表:`create-instance.sh`
|
- [`router-proxy/README.md`](/home/ivan/xuan/nano_project/router-proxy/README.md)
|
||||||
- 查看实例:`list-instances.sh`
|
|
||||||
- 删除实例并可选清理数据:`remove-instance.sh`
|
|
||||||
- 实例注册表与端口分配:`instance-registry.py`
|
|
||||||
|
|
||||||
更具体的使用说明见:
|
|
||||||
|
|
||||||
- `/home/ivan/xuan/nano_project/app-instance/README.md`
|
|
||||||
- `/home/ivan/xuan/nano_project/deploy-control/README.md`
|
|
||||||
- `/home/ivan/xuan/nano_project/router-proxy/README.md`
|
|
||||||
- `/home/ivan/xuan/nano_project/authz-service/README.md`
|
|
||||||
|
|
||||||
## 后续建议
|
|
||||||
|
|
||||||
下一步可以在这三个目录下分别补:
|
|
||||||
|
|
||||||
- `.env` 模板
|
|
||||||
- portal 到部署机的创建实例调用
|
|
||||||
- portal 登录后的统一账号查找和跳转联调
|
|
||||||
- authz-service 的控制面接入和部署编排
|
|
||||||
|
|||||||
5
auth-portal/src/.env.example
Normal file
5
auth-portal/src/.env.example
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# auth-portal server-side runtime config
|
||||||
|
|
||||||
|
AUTHZ_API_BASE_URL=http://nano-authz-service:19090
|
||||||
|
DEPLOY_API_BASE_URL=http://nano-deploy-control:8090
|
||||||
|
DEPLOY_API_TOKEN=change-me
|
||||||
@ -10,6 +10,10 @@ Dedicated login/register frontend for nanobot containers.
|
|||||||
|
|
||||||
Registration now goes through AuthZ, while login/runtime lookup still uses deploy-control:
|
Registration now goes through AuthZ, while login/runtime lookup still uses deploy-control:
|
||||||
|
|
||||||
|
See also:
|
||||||
|
|
||||||
|
- [`.env.example`](/home/ivan/xuan/nano_project/auth-portal/src/.env.example)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
AUTHZ_API_BASE_URL=http://127.0.0.1:19090
|
AUTHZ_API_BASE_URL=http://127.0.0.1:19090
|
||||||
DEPLOY_API_BASE_URL=http://127.0.0.1:8090
|
DEPLOY_API_BASE_URL=http://127.0.0.1:8090
|
||||||
|
|||||||
9
authz-service/.env.example
Normal file
9
authz-service/.env.example
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# authz-service runtime config
|
||||||
|
|
||||||
|
AUTHZ_ISSUER=http://nano-authz-service:19090
|
||||||
|
AUTHZ_INTERNAL_TOKEN=change-me
|
||||||
|
AUTHZ_ACCESS_TOKEN_TTL_SECONDS=3600
|
||||||
|
AUTHZ_UPSTREAM_TIMEOUT_SECONDS=15
|
||||||
|
|
||||||
|
DEPLOY_API_BASE_URL=http://nano-deploy-control:8090
|
||||||
|
DEPLOY_API_TOKEN=change-me
|
||||||
@ -10,8 +10,8 @@
|
|||||||
- 初始化数据目录并启动 `uvicorn`
|
- 初始化数据目录并启动 `uvicorn`
|
||||||
- `start-authz.sh`
|
- `start-authz.sh`
|
||||||
- 本地或服务器快速启动脚本
|
- 本地或服务器快速启动脚本
|
||||||
- `env_template`
|
- `.env.example`
|
||||||
- 常用环境变量模板
|
- 推荐的环境变量模板
|
||||||
- `runtime/seed-data/`
|
- `runtime/seed-data/`
|
||||||
- 空白初始化数据
|
- 空白初始化数据
|
||||||
- `src/`
|
- `src/`
|
||||||
@ -29,7 +29,11 @@
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /home/ivan/xuan/nano_project/authz-service
|
cd /home/ivan/xuan/nano_project/authz-service
|
||||||
AUTHZ_INTERNAL_TOKEN='change-me' ./start-authz.sh --build
|
cp .env.example .env
|
||||||
|
set -a
|
||||||
|
. ./.env
|
||||||
|
set +a
|
||||||
|
./start-authz.sh --build
|
||||||
```
|
```
|
||||||
|
|
||||||
启动后验证:
|
启动后验证:
|
||||||
|
|||||||
28
deploy-control/.env.example
Normal file
28
deploy-control/.env.example
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# deploy-control runtime config
|
||||||
|
|
||||||
|
DEPLOY_CONTROL_HOST=0.0.0.0
|
||||||
|
DEPLOY_CONTROL_PORT=8090
|
||||||
|
DEPLOY_CONTROL_API_TOKEN=change-me
|
||||||
|
|
||||||
|
APP_INSTANCE_IMAGE=nano/app-instance:latest
|
||||||
|
APP_INSTANCE_NETWORK_NAME=nano-instance-edge
|
||||||
|
|
||||||
|
APP_INSTANCE_PROVIDER=openai
|
||||||
|
APP_INSTANCE_MODEL=openai/gpt-5
|
||||||
|
APP_INSTANCE_API_KEY=sk-xxxxxxxx
|
||||||
|
APP_INSTANCE_API_BASE=
|
||||||
|
|
||||||
|
# Used as a fallback when authz-service does not explicitly pass authz_base_url.
|
||||||
|
DEFAULT_AUTHZ_BASE_URL=http://nano-authz-service:19090
|
||||||
|
|
||||||
|
DEPLOY_PUBLIC_SCHEME=http
|
||||||
|
DEPLOY_PUBLIC_BASE_DOMAIN=203.0.113.10.nip.io
|
||||||
|
DEPLOY_PUBLIC_HOST_TEMPLATE={slug}.{base_domain}
|
||||||
|
DEPLOY_PUBLIC_PORT=8088
|
||||||
|
DEPLOY_AUTO_START_PROXY=1
|
||||||
|
DEPLOY_HEALTH_TIMEOUT_SECONDS=60
|
||||||
|
DEPLOY_HEALTH_INTERVAL_SECONDS=1
|
||||||
|
|
||||||
|
# Passed through to create-instance.sh when the app-instance image is rebuilt.
|
||||||
|
AUTH_PORTAL_URL=http://203.0.113.10:3081
|
||||||
|
AUTH_PORTAL_PORT=3081
|
||||||
@ -23,6 +23,10 @@
|
|||||||
- `DEPLOY_PUBLIC_SCHEME`
|
- `DEPLOY_PUBLIC_SCHEME`
|
||||||
- `APP_INSTANCE_NETWORK_NAME`
|
- `APP_INSTANCE_NETWORK_NAME`
|
||||||
|
|
||||||
|
建议直接参考:
|
||||||
|
|
||||||
|
- [`.env.example`](/home/ivan/xuan/nano_project/deploy-control/.env.example)
|
||||||
|
|
||||||
默认实例 URL 形如:
|
默认实例 URL 形如:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|||||||
9
router-proxy/.env.example
Normal file
9
router-proxy/.env.example
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# router-proxy startup config
|
||||||
|
|
||||||
|
PROXY_IMAGE=nginx:1.27-alpine
|
||||||
|
PROXY_CONTAINER_NAME=nano-router-proxy
|
||||||
|
PROXY_NETWORK_NAME=nano-instance-edge
|
||||||
|
PROXY_HTTP_PORT=8088
|
||||||
|
|
||||||
|
REGISTRY_PATH=/home/ivan/xuan/nano_project/app-instance/runtime/registry/instances.json
|
||||||
|
OUTPUT_PATH=/home/ivan/xuan/nano_project/router-proxy/runtime/conf.d/instances.conf
|
||||||
@ -23,6 +23,10 @@
|
|||||||
- Docker network:`nano-instance-edge`
|
- Docker network:`nano-instance-edge`
|
||||||
- 对外端口:`8088`
|
- 对外端口:`8088`
|
||||||
|
|
||||||
|
建议直接参考:
|
||||||
|
|
||||||
|
- [`.env.example`](/home/ivan/xuan/nano_project/router-proxy/.env.example)
|
||||||
|
|
||||||
## 启动
|
## 启动
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
Reference in New Issue
Block a user