mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 09:47:23 +00:00
README 从 642 行降到 131 行,只保留简介、核心能力、最小快速开始、文档索引、 改名说明、目录结构与测试入口。其余内容迁到 docs/,中英文索引一一对应: docs/features.md 实现与完整特性清单(原 README 的"实现/特性") docs/configuration.md 配置文件、自动探测模型、多密钥与配额 docs/routing.md 模型路由、AUTO 链、冷却与半冷却、源/适配器、源模板 docs/performance.md 实测内存占用与调优、thinking 预算 docs/webui.md WebUI 使用 docs/adapters.md Lua 适配器协议与内置适配器清单 docs/gui.md 桌面端 Headless/Desktop 两种产物与构建 docs/development.md 目录职责、开发协作、测试 docs/deployment.md 部署、发行包、目录权限、llmsproxy 迁移与验证清单 中性化:README / README_EN / GUI 注释里的 `Clash Verge` 类比全部改为 「桌面壳 / desktop shell」,仓库内(源码与文档)已无该表述。
138 lines
5.2 KiB
Markdown
138 lines
5.2 KiB
Markdown
# 部署与迁移
|
||
|
||
> 本文档面向运维:单机 systemd 部署、发行包安装、目录与权限、从 `llmsproxy`
|
||
> 改名后的迁移与回滚。
|
||
> 返回 [README](../README.md)。
|
||
|
||
## 1. 单机部署(推荐)
|
||
|
||
仓库根目录的 `deploy.sh` 负责:构建 → 预检配置 → 备份 → 原子替换二进制 →
|
||
重启服务 → 后置校验。它**不**修改源码,也**不**假设全新机器。
|
||
|
||
```bash
|
||
sudo ./deploy.sh # 默认读取仓库内 config.yaml
|
||
sudo ./deploy.sh --config other.yaml # 投放并部署另一份配置
|
||
```
|
||
|
||
部署目标(改名后):
|
||
|
||
| 项 | 路径 |
|
||
|---|---|
|
||
| 二进制 | `/usr/local/bin/modelrouter` |
|
||
| 配置 | `/etc/modelrouter/config.yaml` |
|
||
| 适配器 | `/etc/modelrouter/adapters/` |
|
||
| 插件(可选) | `/etc/modelrouter/plugins/`(需在配置里设 `plugin_dir`) |
|
||
| 主密钥 | `/etc/modelrouter/master.key`(0600) |
|
||
| systemd unit | `/etc/systemd/system/modelrouter.service` |
|
||
|
||
`deploy.sh` 会在以下情况**中止**而不是"看起来成功":
|
||
|
||
- 部署后二进制起不来、或新配置 `-check` 不通过;
|
||
- 凭据无法解封(`master.key` 丢失 / 与配置不匹配);
|
||
- 检测到改名前的 `/etc/llmsproxy`,但新配置尚未建立(否则会部署出一个
|
||
没有 key、没有源的空实例,所有请求都被拒)。
|
||
|
||
## 2. 发行包安装
|
||
|
||
三个产物由 `packaging/core-dist.sh` 生成到 `cmd/build/dist/`:
|
||
|
||
```text
|
||
modelrouter_<ver>_amd64.deb
|
||
modelrouter-<ver>.x86_64.rpm
|
||
modelrouter-<ver>-linux-amd64.tar.gz
|
||
```
|
||
|
||
deb / rpm 安装后:
|
||
|
||
```bash
|
||
sudo systemctl enable --now modelrouter
|
||
sudo journalctl -u modelrouter -f
|
||
```
|
||
|
||
tar 包内只有:`modelrouter`、`config.example.yaml`、`modelrouter.service`、
|
||
`migrate-to-modelrouter.sh`、`adapters/`。
|
||
|
||
**发行包不含业务插件**(`channels` / `billing` / `quota` / `usage` 等)。
|
||
它们保留在仓库中作为可选扩展,需要时手工放入 `plugin_dir`,网关不会自动安装、
|
||
覆盖或删除。这是有意的:插件属于运维资产,生命周期不与内核绑定。
|
||
|
||
首次启动会在 `/etc/modelrouter/config.yaml` 生成一份**随机 admin key** 的配置,
|
||
key 打印在启动日志里。发行包不预置任何可用 key(历史上曾因此泄露过一个真实的
|
||
`sk-gw-local-0001`)。
|
||
|
||
## 3. 目录与权限
|
||
|
||
- `/etc/modelrouter` 是唯一的读写根(systemd unit 用 `ProtectSystem=strict` +
|
||
`ReadWritePaths=/etc/modelrouter` 固化这一点)。
|
||
- `master.key` 必须 0600。当前 unit 以 root 运行:降权到普通用户需要先把
|
||
`master.key` 交给该用户并统一目录属主,否则服务会"带着明文落盘继续跑",
|
||
失败只留一行日志——这是独立变更,不要和加固混在一起。
|
||
- `plugin_dir` 由运维维护;插件自带的状态文件(如 `.channels-store.json`)也在其中。
|
||
|
||
## 4. 从 llmsproxy 迁移
|
||
|
||
二进制、配置目录、服务名、环境变量已统一为 `modelrouter`:
|
||
|
||
| 旧 | 新 |
|
||
|---|---|
|
||
| `/usr/local/bin/llmsproxy` | `/usr/local/bin/modelrouter` |
|
||
| `/etc/llmsproxy/` | `/etc/modelrouter/` |
|
||
| `llmsproxy.service` | `modelrouter.service` |
|
||
| `LLMSPROXY_PLUGIN_DIR` | `MODELROUTER_PLUGIN_DIR` |
|
||
| `LLMSPROXY_XDISPLAY_BASE` | `MODELROUTER_XDISPLAY_BASE` |
|
||
| `LLMS_PROXY_MASTER_KEY` | `MODELROUTER_MASTER_KEY` |
|
||
|
||
迁移脚本**默认 dry-run**,复制而非移动,旧目录永不删除:
|
||
|
||
```bash
|
||
sudo ./packaging/migrate-to-modelrouter.sh # 预演(逐条打印将做什么)
|
||
sudo ./packaging/migrate-to-modelrouter.sh --apply # 执行
|
||
```
|
||
|
||
它做五件事:复制状态目录并改写配置里的旧绝对路径、复核 `master.key` 0600、
|
||
安装新二进制(旧文件保留)、由旧 unit 生成新 unit(改写 ExecStart /
|
||
WorkingDirectory / ReadWritePaths)、复制 `/usr/share` 资源;最后跑
|
||
`modelrouter -check` 并 `systemctl daemon-reload`。
|
||
|
||
确认新服务可用后,再手工清理旧布局(脚本不会删):
|
||
|
||
```bash
|
||
sudo systemctl disable --now llmsproxy.service
|
||
sudo rm -f /etc/systemd/system/llmsproxy.service
|
||
sudo rm -rf /usr/local/bin/llmsproxy /etc/llmsproxy /usr/share/llmsproxy
|
||
```
|
||
|
||
回滚(不需要旧文件被删):
|
||
|
||
```bash
|
||
sudo ./packaging/migrate-to-modelrouter.sh --rollback --apply
|
||
```
|
||
|
||
**读取侧兼容**:旧配置路径与旧环境变量仍被接受,所以"先换二进制、后改 unit"
|
||
这种顺序不会立刻失效。但写入永远落在新路径,迁移完成后不要两台布局混用。
|
||
|
||
## 5. 部署后验证清单
|
||
|
||
```bash
|
||
# 1) 进程与监听
|
||
systemctl status modelrouter --no-pager
|
||
ss -ltnp | grep modelrouter
|
||
|
||
# 2) 鉴权生效(无 key 必须 401)
|
||
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/v1/models
|
||
|
||
# 3) 带 key 能列出模型
|
||
curl -s -H "Authorization: Bearer $KEY" http://127.0.0.1:8080/v1/models | head -c 400
|
||
|
||
# 4) 真实请求走通(证明 LuaJIT 适配器路径未被打断)
|
||
curl -s -H "Authorization: Bearer $KEY" \
|
||
-d '{"model":"AUTO","messages":[{"role":"user","content":"hi"}]}' \
|
||
http://127.0.0.1:8080/v1/chat/completions | head -c 400
|
||
|
||
# 5) 仓库文件与生产文件一致(部署脚本的收尾检查)
|
||
sha256sum /usr/local/bin/modelrouter build/modelrouter
|
||
```
|
||
|
||
第 4 步失败但第 3 步成功,通常是适配器或上游凭据问题,不是部署问题:
|
||
查看 `journalctl -u modelrouter -n 100`。
|