212 lines
8.0 KiB
Markdown
212 lines
8.0 KiB
Markdown
# AGENTS.md — Sub2API 部署与发版
|
||
|
||
## 项目概述
|
||
|
||
Sub2API — AI API 网关平台,Go + Vue 3 前后端一体,Ent ORM,支持多账户管理、API 密钥分发、Token 级计费、智能调度、支付集成。
|
||
|
||
- 上游: `https://github.com/Wei-Shaw/sub2api`
|
||
- 本地: `/Users/qingse/Sync/local-git/sub2api`
|
||
- 当前稳定版: `v0.1.133`
|
||
- 许可证: LGPL v3
|
||
|
||
## 部署留痕规则
|
||
|
||
所有远程部署、迁移、域名切换、证书、反代、Compose、数据库、Redis、Mihomo 或代理配置变化,都必须在当前仓库留痕。
|
||
|
||
- 根级 `AGENTS.md` 只记录规则、索引和通用流程。
|
||
- 每台服务器必须在 `ops/remote/` 下单独一个子目录。
|
||
- 服务器目录必须记录域名、IP、服务器名、Tabby profile、部署方式、部署架构、运行检查和操作记录。
|
||
- 当前实际生效配置副本必须放在对应服务器目录的 `current/` 下,例如 `docker-compose.yml`、`nginx-sub2api.conf` 或 `Caddyfile`。
|
||
- 计划但尚未部署的配置放在 `planned/` 下,不能写成当前事实。
|
||
- `.env`、数据库密码、JWT/TOTP 密钥、Mihomo 订阅和真实代理配置只允许放在被 `.gitignore` 排除的 `secrets/` 或 `backups/` 中,禁止提交。
|
||
- 通过 Tabby 操作远程后,必须同步更新对应服务器目录,避免远程真实状态和项目记录漂移。
|
||
|
||
当前远程部署索引见 `ops/remote/README.md`。每个服务器目录至少包含:
|
||
|
||
```text
|
||
ops/remote/<server>-sub2api/
|
||
├── README.md # 服务器级部署记录
|
||
├── current/ # 当前远程生效配置副本
|
||
├── planned/ # 计划配置,未部署时使用
|
||
├── secrets/README.md # 敏感配置保存说明,真实文件不提交
|
||
├── backups/.gitkeep # 远程备份说明或占位,真实备份不提交
|
||
└── .gitignore # 排除密钥、订阅和备份
|
||
```
|
||
|
||
## 远程部署索引
|
||
|
||
| 目录 | Tabby 连接 | 公网入口 | 状态 |
|
||
|------|------------|----------|------|
|
||
| `ops/remote/jppro-sub2api/` | `个人-JPpro-akile-0504-1c1g` | `https://proxy.api.lilifamily.com` / `https://jp.proxy.api.lilifamily.com` | proxy-ng 公开入口节点,回源到 3c4g origin |
|
||
| `ops/remote/us-racknerd-0425-sub2api/` | `个人-US-racknerd-0425-1c1g` | `https://pai.cyan2000.uk` | 旧机,迁移来源和回滚来源 |
|
||
| `ops/remote/us-racknerd-0526-sub2api/` | `个人-US-racknerd-0526-3c4g` | `https://origin.proxy.api.lilifamily.com` / `https://catproxy.lilifamily.com` | Sub2API 受限 origin 和公开直连主站入口 |
|
||
|
||
## JPpro 当前 proxy-ng 记录
|
||
|
||
| 项目 | 详情 |
|
||
|------|------|
|
||
| 服务器 | JP Pro VPS `151.242.164.72`,Debian Trixie 1C1G20G |
|
||
| 域名 | `proxy.api.lilifamily.com`、`jp.proxy.api.lilifamily.com` |
|
||
| Tabby 连接 | `个人-JPpro-akile-0504-1c1g` |
|
||
| 部署方式 | apt 安装 nginx + Certbot,作为 proxy-ng 入口中转 |
|
||
| 回源目标 | `https://origin.proxy.api.lilifamily.com` |
|
||
| 访问 | `https://proxy.api.lilifamily.com/`、`https://jp.proxy.api.lilifamily.com/` |
|
||
| 详细记录 | `ops/remote/jppro-sub2api/` |
|
||
|
||
当前 JPpro 不运行 Sub2API、PostgreSQL、Redis、Caddy 或账号出口代理;只运行 nginx 反向代理。当前已启用独立 origin 回源、3c4g 来源 IP 白名单和 `X-Proxy-Ng-Token` 校验。
|
||
|
||
## JPpro 历史部署记录
|
||
|
||
| 项目 | 详情 |
|
||
|------|------|
|
||
| 服务器 | JP Pro VPS `151.242.164.72`,Debian Trixie 1C1G20G |
|
||
| 域名 | `proxy.api.cyan2000.uk` |
|
||
| Tabby 连接 | `个人-JPpro-akile-0504-1c1g` |
|
||
| 部署目录 | `/opt/sub2api/`,已于 2026-05-26 清理 |
|
||
| 访问 | `https://proxy.api.cyan2000.uk/`,当前未在 JPpro 上提供服务 |
|
||
| 详细记录 | `ops/remote/jppro-sub2api/` |
|
||
|
||
### 远程目录结构
|
||
|
||
```
|
||
/opt/sub2api/
|
||
├── docker-compose.yml # 官方 docker-compose.yml + Caddy
|
||
├── .env # 密钥配置 (chmod 600)
|
||
└── Caddyfile # Caddy 反向代理配置
|
||
```
|
||
|
||
数据存储在 Docker 命名卷:`sub2api_data`、`postgres_data`、`redis_data`、`caddy_data`、`caddy_config`。
|
||
|
||
### 历史 Docker 服务架构
|
||
|
||
```
|
||
Browser :443 (HTTPS) → Caddy → sub2api :8080 (内部) → postgres :5432 (内部)
|
||
:80 → 301 redirect → redis :6379 (内部)
|
||
```
|
||
|
||
| 容器 | 镜像 | 角色 |
|
||
|------|------|------|
|
||
| `sub2api-caddy` | `caddy:2-alpine` | HTTPS 自动证书 + 反向代理 |
|
||
| `sub2api` | `weishaw/sub2api:latest` | Go 后端 + 内嵌 Vue 前端 |
|
||
| `sub2api-postgres` | `postgres:18-alpine` | 主数据库 |
|
||
| `sub2api-redis` | `redis:8-alpine` | 缓存 |
|
||
|
||
### Caddy 配置
|
||
|
||
```
|
||
proxy.api.cyan2000.uk {
|
||
reverse_proxy sub2api:8080
|
||
encode gzip
|
||
}
|
||
```
|
||
|
||
Caddy 自动从 Let's Encrypt 获取和管理 TLS 证书,HTTP(:80) 自动 301 跳转到 HTTPS(:443)。
|
||
|
||
## 发版流程
|
||
|
||
远程服务器可直接拉取 Docker Hub,常规升级只需 pull + restart。
|
||
|
||
### 常规升级(官方镜像)
|
||
|
||
```bash
|
||
cd /opt/sub2api
|
||
docker compose pull sub2api
|
||
docker compose up -d
|
||
```
|
||
|
||
### 本地编译部署(二开修改时使用)
|
||
|
||
当 GitHub 不可达需要国内 GOPROXY,或需要本地修改代码后部署时:
|
||
|
||
```bash
|
||
# 1. 拉取代码
|
||
cd /Users/qingse/Sync/local-git/sub2api
|
||
git fetch ea-ali
|
||
git checkout <tag>
|
||
|
||
# 2. 构建前端
|
||
cd frontend && pnpm install --frozen-lockfile && pnpm run build
|
||
|
||
# 3. 交叉编译 Go
|
||
cd ../backend
|
||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
|
||
GOPROXY=https://goproxy.cn,direct \
|
||
go build -tags embed -ldflags="-s -w -X main.Version=<版本>" -trimpath \
|
||
-o /tmp/sub2api ./cmd/server
|
||
|
||
# 4. 构建最小 Docker 镜像
|
||
mkdir -p /tmp/sub2api-build/{deploy,backend/resources}
|
||
cp /tmp/sub2api /tmp/sub2api-build/
|
||
cp -r ../backend/resources/* /tmp/sub2api-build/backend/resources/
|
||
cp ../deploy/docker-entrypoint.sh /tmp/sub2api-build/deploy/
|
||
|
||
cat > /tmp/sub2api-build/Dockerfile << 'EOF'
|
||
FROM alpine:latest
|
||
RUN apk add --no-cache ca-certificates tzdata su-exec libpq wget
|
||
RUN addgroup -g 1000 sub2api && adduser -u 1000 -G sub2api -s /bin/sh -D sub2api
|
||
COPY sub2api /app/sub2api
|
||
COPY backend/resources /app/resources
|
||
COPY deploy/docker-entrypoint.sh /app/docker-entrypoint.sh
|
||
RUN chmod +x /app/docker-entrypoint.sh && mkdir -p /app/data && chown sub2api:sub2api /app/data
|
||
EXPOSE 8080
|
||
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||
CMD wget -q -T 5 -O /dev/null http://localhost:8080/health || exit 1
|
||
WORKDIR /app
|
||
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
||
CMD ["/app/sub2api"]
|
||
EOF
|
||
|
||
docker build --platform linux/amd64 -t sub2api:<版本> /tmp/sub2api-build
|
||
|
||
# 5. 导出上传
|
||
docker save sub2api:<版本> | gzip > /tmp/sub2api-<版本>.tar.gz
|
||
# Tabby SFTP: open_profile(个人-JPpro-akile-0504-1c1g) → sftp_upload → /tmp/
|
||
|
||
# 6. 远程部署
|
||
docker load < /tmp/sub2api-<版本>.tar.gz
|
||
cd /opt/sub2api
|
||
sed -i 's|image:.*|image: sub2api:<版本>|' docker-compose.yml
|
||
docker compose up -d
|
||
|
||
# 7. 清理
|
||
rm -rf /tmp/sub2api-build /tmp/sub2api /tmp/sub2api-*.tar.gz
|
||
```
|
||
|
||
## 运维命令
|
||
|
||
```bash
|
||
# 查看服务状态
|
||
cd /opt/sub2api && docker compose ps
|
||
|
||
# 查看日志
|
||
docker logs sub2api --tail 50 -f
|
||
|
||
# 查询数据库
|
||
docker exec sub2api-postgres psql -U sub2api -d sub2api -c "SELECT ..."
|
||
|
||
# 重启服务
|
||
cd /opt/sub2api && docker compose up -d
|
||
|
||
# 停止服务
|
||
cd /opt/sub2api && docker compose down
|
||
|
||
# 数据备份
|
||
cd /opt/sub2api && tar czf /tmp/sub2api-backup-$(date +%Y%m%d).tar.gz data/ postgres_data/ redis_data/
|
||
```
|
||
|
||
## Git 远程
|
||
|
||
| 远程 | URL | 角色 |
|
||
|------|-----|------|
|
||
| `origin` | `https://github.com/Wei-Shaw/sub2api.git` | 上游 |
|
||
| `ea-ali` | `ssh://git@101.200.34.71:2222/zizi-al/sub2api.git` | 可写开发远程 |
|
||
|
||
## 注意事项
|
||
|
||
- Go 编译必须加 `-tags embed`,否则前端不会嵌入二进制
|
||
- 前端 build 输出到 `backend/internal/web/dist`,Go 编译时通过 `//go:embed` 嵌入
|
||
- GitHub 和 Docker Hub 在国内网络不可达时,Go proxy 用 `goproxy.cn`,Docker base image 用本地缓存
|
||
- 远程服务器可访问 Docker Hub,postgres:18-alpine 和 redis:8-alpine 自动拉取
|
||
- `.env` 文件权限必须是 600,包含数据库密码和 JWT 密钥
|
||
- 首次启动会自动创建管理员账号(`AUTO_SETUP=true`)
|