sub2api/AGENTS.md
zizi a2953b8a2f
Some checks failed
CI / test (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
Security Scan / backend-security (push) Has been cancelled
Security Scan / frontend-security (push) Has been cancelled
docs(ops): record sub2api 0.1.133 deployment
2026-06-05 17:23:26 +08:00

212 lines
8.0 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.

# 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 Hubpostgres:18-alpine 和 redis:8-alpine 自动拉取
- `.env` 文件权限必须是 600包含数据库密码和 JWT 密钥
- 首次启动会自动创建管理员账号(`AUTO_SETUP=true`