mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-07 09:55:29 +08:00
252 lines
7.0 KiB
Markdown
252 lines
7.0 KiB
Markdown
# DS2API 部署指南(Go)
|
||
|
||
语言 / Language: [中文](DEPLOY.md) | [English](DEPLOY.en.md)
|
||
|
||
本指南基于当前 Go 代码库。
|
||
|
||
## 部署方式
|
||
|
||
- 本地运行:`go run ./cmd/ds2api`
|
||
- Docker:`docker-compose up -d`
|
||
- Vercel:`api/index.go` serverless 入口
|
||
- Linux 服务化:systemd
|
||
|
||
## 0. 前置要求
|
||
|
||
- Go 1.24+
|
||
- Node.js 20+(仅在需要本地构建 WebUI 时)
|
||
- `config.json` 或 `DS2API_CONFIG_JSON`
|
||
|
||
## 1. 本地运行
|
||
|
||
```bash
|
||
git clone https://github.com/CJackHwang/ds2api.git
|
||
cd ds2api
|
||
|
||
cp config.example.json config.json
|
||
# 编辑 config.json
|
||
|
||
go run ./cmd/ds2api
|
||
```
|
||
|
||
默认监听 `5001`,可通过 `PORT` 覆盖。
|
||
|
||
构建 WebUI(可选,仅当 `/admin` 缺少静态文件时):
|
||
|
||
```bash
|
||
./scripts/build-webui.sh
|
||
|
||
# 或依赖自动构建(默认本地开启)
|
||
# DS2API_AUTO_BUILD_WEBUI=true go run ./cmd/ds2api
|
||
```
|
||
|
||
## 2. Docker 部署
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
# 编辑 .env
|
||
|
||
docker-compose up -d
|
||
docker-compose logs -f
|
||
```
|
||
|
||
更新镜像:
|
||
|
||
```bash
|
||
docker-compose up -d --build
|
||
```
|
||
|
||
说明:
|
||
|
||
- `Dockerfile` 使用多阶段构建(WebUI + Go 二进制)
|
||
- 容器内默认启动命令:`/usr/local/bin/ds2api`
|
||
|
||
## 3. Vercel 部署
|
||
|
||
- serverless 入口:`api/index.go`
|
||
- 路由与缓存头:`vercel.json`
|
||
- 构建阶段会自动执行 `npm ci --prefix webui && npm run build --prefix webui`
|
||
- `vercel.json` 已将 `/admin/assets/*` 与 `/admin` 页面走静态产物,`/admin/*` API 仍走 `api/index`
|
||
- 为缓解 Go Runtime 的流式缓冲,`/v1/chat/completions` 在 Vercel 上会优先走 `api/chat-stream.js`(Node Runtime)
|
||
- `api/chat-stream.js` 对非流式请求或 `tools` 请求会自动回退到 Go 入口(内部 `__go=1`)
|
||
- `api/chat-stream.js` 仅负责流式数据转发与 SSE 转换;鉴权、账号选择、会话创建、PoW 计算仍由 Go 内部 prepare 接口完成(仅 Vercel 启用)
|
||
- Go prepare 会创建流式 lease,Node 在流结束后回调 release;账号占用语义与 Go 原生流式保持一致
|
||
- `vercel.json` 已将 `api/chat-stream.js` 与 `api/index.go` 的 `maxDuration` 设为 `300`(受套餐上限约束)
|
||
|
||
至少配置环境变量:
|
||
|
||
- `DS2API_ADMIN_KEY`
|
||
- `DS2API_CONFIG_JSON`(JSON 或 Base64)
|
||
|
||
可选:
|
||
|
||
- `VERCEL_TOKEN`
|
||
- `VERCEL_PROJECT_ID`
|
||
- `VERCEL_TEAM_ID`
|
||
- `DS2API_ACCOUNT_MAX_INFLIGHT`(每账号并发上限,默认 `2`)
|
||
- `DS2API_ACCOUNT_CONCURRENCY`(同上别名)
|
||
- `DS2API_ACCOUNT_MAX_QUEUE`(等待队列上限,默认=`recommended_concurrency`)
|
||
- `DS2API_ACCOUNT_QUEUE_SIZE`(同上别名)
|
||
- `DS2API_VERCEL_INTERNAL_SECRET`(可选,Vercel 混合流式链路内部鉴权;未设置时回退使用 `DS2API_ADMIN_KEY`)
|
||
- `DS2API_VERCEL_STREAM_LEASE_TTL_SECONDS`(可选,流式 lease 过期秒数,默认 `900`)
|
||
|
||
并发建议值会动态按 `账号数量 × 每账号并发上限` 计算(默认即 `账号数量 × 2`)。
|
||
当 in-flight 满时,请求先进入等待队列;默认队列上限等于建议并发值,因此默认 429 阈值约为 `账号数量 × 4`。
|
||
|
||
说明:
|
||
- 仓库不提交 `static/admin` 构建产物
|
||
- Vercel / Docker 构建阶段自动生成 WebUI 静态文件
|
||
|
||
部署后建议先访问:
|
||
|
||
- `/healthz`
|
||
- `/v1/models`
|
||
- `/admin`
|
||
|
||
## 3.1 GitHub Release 自动构建
|
||
|
||
仓库包含 `.github/workflows/release-artifacts.yml`:
|
||
|
||
- 仅在 Release `published` 时触发
|
||
- 不在 `push` 时触发
|
||
- 自动构建 Linux/macOS/Windows 二进制包并上传到 Release Assets
|
||
- 生成 `sha256sums.txt` 供校验
|
||
|
||
## 3.2 Vercel 常见报错排查
|
||
|
||
若看到类似报错:
|
||
|
||
```text
|
||
Error: Command failed: go build -ldflags -s -w -o .../bootstrap .../main__vc__go__.go
|
||
```
|
||
|
||
通常是 Vercel 项目里的 Go 构建参数配置不正确(`-ldflags` 没有作为一个整体字符串传递)。
|
||
|
||
处理方式:
|
||
|
||
1. 进入 Vercel Project Settings -> Build and Development Settings
|
||
2. 清空自定义 Go Build Flags / Build Command(推荐)
|
||
3. 若必须设置 ldflags,使用 `-ldflags=\"-s -w\"`(保证它是一个参数)
|
||
4. 确认仓库 `go.mod` 为受支持版本(当前为 `go 1.24`)
|
||
5. 重新部署(建议 `Redeploy` 并清缓存)
|
||
|
||
另一个常见根因(Go 单仓 + `internal/`):
|
||
|
||
```text
|
||
... use of internal package ds2api/internal/server not allowed
|
||
```
|
||
|
||
这通常发生在 Vercel Go 入口文件直接 `import internal/...`。
|
||
当前仓库已通过公开桥接包 `app` 解决:`api/index.go` -> `ds2api/app` -> `internal/server`。
|
||
|
||
若看到类似报错:
|
||
|
||
```text
|
||
No Output Directory named "public" found after the Build completed.
|
||
```
|
||
|
||
说明 Vercel 正在按 `public` 校验前端产物目录。当前仓库会将 WebUI 构建到 `static/admin`,并在 `vercel.json` 使用上级目录 `static` 作为输出根目录:
|
||
|
||
```json
|
||
"outputDirectory": "static"
|
||
```
|
||
|
||
若你在项目设置里手动改过 Output Directory,请同步改为 `static` 或清空让仓库配置生效。
|
||
|
||
若接口返回 Vercel 的 HTML 页面 `Authentication Required`(而不是 JSON),说明被 Vercel Deployment Protection 拦截:
|
||
|
||
- 关闭该部署/环境的 Protection(推荐用于公开 API)
|
||
- 或给请求加 `x-vercel-protection-bypass`
|
||
- 若仅是 Vercel 内部 Node->Go 调用被拦截,可设置 `VERCEL_AUTOMATION_BYPASS_SECRET`(或 `DS2API_VERCEL_PROTECTION_BYPASS`)
|
||
|
||
Vercel 流式说明(重要):
|
||
|
||
- Vercel 的 Go Runtime 存在平台层响应缓冲,因此本项目在 Vercel 上采用“Go prepare + Node stream”的混合链路来恢复实时 SSE。
|
||
- 该适配只在 Vercel 生效;本地与 Docker 仍走纯 Go 链路。
|
||
|
||
## 4. 反向代理(Nginx)
|
||
|
||
如果在 Nginx 后挂载,建议关闭缓冲以保证 SSE:
|
||
|
||
```nginx
|
||
location / {
|
||
proxy_pass http://127.0.0.1:5001;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Connection "";
|
||
proxy_buffering off;
|
||
proxy_cache off;
|
||
chunked_transfer_encoding on;
|
||
tcp_nodelay on;
|
||
}
|
||
```
|
||
|
||
## 5. systemd 示例(Linux)
|
||
|
||
```ini
|
||
[Unit]
|
||
Description=DS2API (Go)
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
WorkingDirectory=/opt/ds2api
|
||
Environment=PORT=5001
|
||
Environment=DS2API_CONFIG_PATH=/opt/ds2api/config.json
|
||
Environment=DS2API_ADMIN_KEY=admin
|
||
ExecStart=/opt/ds2api/ds2api
|
||
Restart=always
|
||
RestartSec=5
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
```
|
||
|
||
常用命令:
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable ds2api
|
||
sudo systemctl start ds2api
|
||
sudo systemctl status ds2api
|
||
```
|
||
|
||
## 6. 部署后检查
|
||
|
||
```bash
|
||
curl -s http://127.0.0.1:5001/healthz
|
||
curl -s http://127.0.0.1:5001/readyz
|
||
curl -s http://127.0.0.1:5001/v1/models
|
||
```
|
||
|
||
如果你依赖管理台接口,再检查:
|
||
|
||
```bash
|
||
curl -s http://127.0.0.1:5001/admin
|
||
```
|
||
|
||
## 7. 发布前本地回归(推荐)
|
||
|
||
建议在发布前执行一次完整测试集(真实账号链路):
|
||
|
||
```bash
|
||
./scripts/testsuite/run-live.sh
|
||
```
|
||
|
||
可选参数示例:
|
||
|
||
```bash
|
||
go run ./cmd/ds2api-tests \
|
||
--config config.json \
|
||
--admin-key admin \
|
||
--out artifacts/testsuite \
|
||
--timeout 120 \
|
||
--retries 2
|
||
```
|
||
|
||
测试集会自动执行:
|
||
|
||
- 语法/构建/单测 preflight
|
||
- 隔离副本配置启动服务(不污染原始 `config.json`)
|
||
- 真实调用场景验证(OpenAI/Claude/Admin/并发/toolcall/流式)
|
||
- 全量请求与响应日志落盘(用于故障复盘)
|