Files
openai_node/DEPLOY.md
T

344 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# openai_node · 生产部署文档
本文说明如何在 **VPS** 上部署本网关,并通过 **宝塔面板** 反向代理、**frp** 汇聚多台本地 Ollama 节点。适用于当前推荐拓扑:
- 网关监听:**8150**
- 宝塔反代:域名 → `127.0.0.1:8150`
- 各 PC 模型端口:**33133318**frp 映射到 VPS 本机 `127.0.0.1`
代码仓库:[https://git.bz121.com/dekun/openai_node.git](https://git.bz121.com/dekun/openai_node.git)
---
## 1. 部署拓扑
```
Internet
┌─────────────────┐
│ VPS │
│ 宝塔 Nginx:443 │
│ │ │
│ ▼ │
│ openai_node │
│ :8150 │
│ │ │
│ 127.0.0.1:3313 ├─── frp ─── PC1 Ollama :3313
│ 127.0.0.1:3314 ├─── frp ─── PC2 Ollama :3314
│ 127.0.0.1:3315 ├─── frp ─── PC3 Ollama :3315
└─────────────────┘
```
要点:
1. **不要**把 3313 等端口直接暴露到公网,仅 VPS 本机访问。
2. **不要**让宝塔直接把域名反代到各 PC;应只反代到 **8150**,由网关按 `model` 调度。
3. `nodes.json``host`**`127.0.0.1`**`port` 填 frp 映射后的端口。
---
## 2. 前置条件
| 组件 | 版本建议 | 用途 |
|------|----------|------|
| Python | 3.10+ | 运行网关 |
| Node.js | LTS | 安装 PM2 |
| PM2 | 最新 | 进程守护 |
| 宝塔 | 7.x+ | Nginx 反代、SSL |
| frp | 客户端 + 服务端 | 内网穿透(可用其它方案,原理相同) |
各 PC 已安装 **Ollama** 并监听本地端口(如 3313),且与 VPS 网络可达(通过 frp)。
---
## 3. 在 VPS 上部署网关
### 3.1 克隆代码
```bash
cd /www/wwwroot # 按宝塔网站目录调整
git clone https://git.bz121.com/dekun/openai_node.git
cd openai_node
```
### 3.2 虚拟环境与依赖
```bash
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt -U
```
### 3.3 配置文件
```bash
cp gateway.json.example gateway.json
cp nodes.json.example nodes.json
chmod 600 gateway.json nodes.json
```
编辑 **`gateway.json`**:设置 `username``password``api_key` 可留空自动生成。
编辑 **`nodes.json`**(示例三台):
```json
{
"nodes": [
{
"id": "node-1",
"name": "书房电脑",
"host": "127.0.0.1",
"port": 3313,
"enabled": true,
"max_concurrent": 1,
"models": [
{ "id": "qwen2.5:14b", "label": "千问 14B" }
]
}
]
}
```
`models[].id` 必须与 Ollama 模型名、API 请求中的 `model` **完全一致**
也可部署后浏览器打开 **系统设置** 页面维护(需先登录)。
### 3.4 环境变量
| 变量 | 生产建议 |
|------|----------|
| `JWT_SECRET` | **必改**,长随机字符串 |
| `GATEWAY_PORT` | `8150`(与 PM2、宝塔一致) |
可选:
| 变量 | 说明 |
|------|------|
| `STATS_DB` | 统计库路径,默认 `gateway_stats.db` |
| `NODES_CONFIG` | 节点配置路径,默认 `nodes.json` |
| `UPSTREAM_URL` | 仅在没有配置 `nodes.json` 节点时作为单机上流 |
### 3.5 手动试跑
```bash
export JWT_SECRET="你的随机密钥"
python -m uvicorn main:app --host 0.0.0.0 --port 8150
```
确认:
```bash
curl -s http://127.0.0.1:8150/api/models/cards | head
curl -s http://127.0.0.1:3313/v1/models # frp 通了才有返回
```
浏览器访问 `http://VPS_IP:8150`,首页应出现模型卡片。
---
## 4. PM2 守护
项目已包含 **`ecosystem.config.cjs`**(端口 **8150**)。
### 4.1 修改 PM2 配置
编辑 `ecosystem.config.cjs``env.JWT_SECRET` 为生产密钥。
### 4.2 启动
```bash
cd /www/wwwroot/openai_node
source venv/bin/activate
pm2 start ecosystem.config.cjs
pm2 save
pm2 status
```
常用命令:
| 命令 | 作用 |
|------|------|
| `pm2 logs llm-gateway` | 查看日志 |
| `pm2 restart llm-gateway` | 重启(改代码/配置后) |
| `pm2 stop llm-gateway` | 停止 |
更新代码后:
```bash
git pull
source venv/bin/activate
pip install -r requirements.txt -U
pm2 restart llm-gateway
```
### 4.3 开机自启
```bash
pm2 save
pm2 startup
# 按提示执行输出的 sudo 命令
```
---
## 5. 宝塔反向代理
### 5.1 添加站点
宝塔 → **网站** → 添加站点 → 绑定域名 → 申请 **SSL**Lets Encrypt)。
### 5.2 反向代理到 8150
网站 → **设置****反向代理** → 添加:
| 项 | 值 |
|----|-----|
| 目标 URL | `http://127.0.0.1:8150` |
| 发送域名 | `$host` |
**配置文件** 或「高级」中建议补充(流式 LLM 必备):
```nginx
location / {
proxy_pass http://127.0.0.1:8150;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
```
说明:
- `X-Forwarded-For` / `X-Real-IP` 用于网关 **流量统计** 记录真实客户端 IP。
- `proxy_buffering off` 与长超时避免流式输出卡顿或中断。
### 5.3 验证
```bash
curl -I https://你的域名/
```
应返回 200。登录 Web → 首页查看模型卡片状态。
---
## 6. frp 多机穿透(示例)
以下为常见做法,按你实际 frp 版本调整。
### 6.1 VPS 运行 frps
`/etc/frp/frps.toml` 示例:
```toml
bindPort = 7000
```
### 6.2 各 PC 运行 frpc
`/etc/frp/frpc.toml` 示例(书房电脑,本地 Ollama 3313):
```toml
serverAddr = "VPS公网IP"
serverPort = 7000
[[proxies]]
name = "ollama-pc1"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3313
remotePort = 3313
```
其它电脑分别映射 **3314、3315** … 到 VPS 的 **3314、3315**
### 6.3 在 VPS 上验证
```bash
curl http://127.0.0.1:3313/v1/models
curl http://127.0.0.1:3314/v1/models
```
均正常后,在 Web **系统设置** 中为对应节点点击 **测试**,或等待首页健康检查(约 30 秒)变为 **空闲**
---
## 7. Ollama 侧注意
1. Ollama 需监听 `0.0.0.0` 或 frp 能访问的地址(仅内网/frp,勿公网裸露)。
2. API 请求中的 `model` 使用 `ollama list` 中的名称,与 `nodes.json` 一致。
3. 流式统计 Token 依赖响应中的 `usage`;可在请求中加 OpenAI 兼容参数(若上游支持):
```json
"stream_options": { "include_usage": true }
```
---
## 8. 客户端接入
| 项 | 值 |
|----|-----|
| Base URL | `https://你的域名/v1` |
| API Key | `gateway.json` 的 `api_key` 或用户中心复制 |
示例:
```bash
curl https://你的域名/v1/chat/completions \
-H "Authorization: Bearer sk-你的密钥" \
-H "Content-Type: application/json" \
-d '{"model":"qwen2.5:14b","messages":[{"role":"user","content":"hi"}]}'
```
---
## 9. 运维与数据文件
| 路径 | 说明 | 备份 |
|------|------|------|
| `gateway.json` | 账号、API Key | 建议 |
| `nodes.json` | 节点与模型 | 建议 |
| `gateway_stats.db` | 访问与 Token 统计 | 可选 |
| `~/.pm2/logs/` | PM2 日志 | 按需 |
修改 `nodes.json` 或 Web 设置后,**PM2 会自动读入**(`save_nodes_config` 热加载);若仅改环境变量需 `pm2 restart`。
---
## 10. 故障排查
| 现象 | 排查 |
|------|------|
| 首页卡片 **离线** | VPS 上 `curl 127.0.0.1:端口/v1/models`;检查 frp、Ollama 是否启动 |
| **404 未找到模型** | 请求 `model` 与 `nodes.json` 中 `models[].id` 不一致 |
| **502 上游连接失败** | 端口错、frp 断、防火墙;`pm2 logs llm-gateway` |
| 统计 IP 全是 VPS | 宝塔未传 `X-Forwarded-For`,见 §5.2 |
| Token 始终为 0 | 上游未返回 `usage`;流式需 `include_usage` |
| 改 `JWT_SECRET` 后无法进设置 | 重新登录 Web |
---
## 11. 部署检查清单
- [ ] `gateway.json`、`nodes.json` 已配置且权限 `600`
- [ ] `JWT_SECRET` 已修改
- [ ] PM2 进程 `llm-gateway` 在线,端口 **8150**
- [ ] 宝塔 HTTPS 反代到 `127.0.0.1:8150`,流式相关 Nginx 参数已加
- [ ] frp 映射 3313+ 在 VPS 本机 `curl` 通过
- [ ] 首页模型卡片状态为 **空闲** 或 **忙碌**(非长期离线)
- [ ] API 试调用成功,`/stats` 有记录
---
## 12. 相关文档
- 功能与配置总览:[README.md](./README.md)
- 仓库地址:[https://git.bz121.com/dekun/openai_node.git](https://git.bz121.com/dekun/openai_node.git)