Skip to content

new-api 与 sub2api 本地开发与部署

本文面向站点维护者,整理 new-apisub2api 的本地开发、远程数据库联调和生产部署流程。

安全提醒

不要把生产数据库密码、Redis 密码、SSH 私钥、面板地址或真实服务器 IP 写入公开仓库。本文使用占位符展示配置结构,实际值请从密码管理器、服务器环境变量或 1Panel 应用配置中读取。

项目仓库

项目官方仓库Fork
new-apihttps://github.com/QuantumNous/new-apihttps://github.com/2Red1Blue/new-api
sub2apihttps://github.com/mansebia/sub2apihttps://github.com/2Red1Blue/sub2api

本地源码通常放在:

text
~/Code/kaiyuan/cpa/new-api
~/Code/kaiyuan/cpa/sub2api

Git 远程分支策略

origin 指向自己的 fork,用来推送自定义改动;upstream 指向官方仓库,用来同步上游更新。

bash
git remote -v
git fetch upstream
git merge upstream/main
git push origin main

如果希望提交历史更线性,也可以用 rebase,但已经与远程协作的分支要谨慎改写历史。

new-api 本地全量开发

new-api 仓库提供了开发用 compose,包含后端、PostgreSQL 和 Redis,适合不依赖生产数据的本地调试。

bash
cd ~/Code/kaiyuan/cpa/new-api
podman compose -f docker-compose.dev.yml up -d

后端地址:

text
http://localhost:3000

修改 Go 代码后重建:

bash
podman compose -f docker-compose.dev.yml up -d --build new-api

停止服务:

bash
podman compose -f docker-compose.dev.yml down

清空本地数据并重置:

bash
podman compose -f docker-compose.dev.yml down -v

前端开发服务器:

bash
cd ~/Code/kaiyuan/cpa/new-api/web/default
bun install
bun run dev

前端默认访问 http://localhost:3001,API 代理到后端 :3000

远程数据库联调模式

当需要使用服务器上的真实数据调试时,可以通过 SSH 隧道把服务器内网 PostgreSQL 和 Redis 映射到本地。

text
本地 5433 -> SSH 隧道 -> 服务器 127.0.0.1:5432 PostgreSQL
本地 6381 -> SSH 隧道 -> 服务器 127.0.0.1:6379 Redis

建立隧道:

bash
ssh -N \
  -L 5433:127.0.0.1:5432 \
  -L 6381:127.0.0.1:6379 \
  qianshan-oci

验证端口:

bash
nc -z 127.0.0.1 5433 && echo "PG OK"
nc -z 127.0.0.1 6381 && echo "Redis OK"

new-api 连接远程数据库调试

容器模式适合日常联调:

bash
cd ~/Code/kaiyuan/cpa/new-api
podman compose -f docker-compose.remote-db.yml up -d
podman compose -f docker-compose.remote-db.yml logs -f new-api

本地 Go 进程模式适合 GoLand 或 VS Code 打断点。由于后端会嵌入前端构建产物,调试前先准备占位文件:

bash
cd ~/Code/kaiyuan/cpa/new-api
mkdir -p web/default/dist web/classic/dist
printf '<!doctype html><html><body>use frontend dev server</body></html>' > web/default/dist/index.html
printf '<!doctype html><html><body>use frontend dev server</body></html>' > web/classic/dist/index.html

启动后端:

bash
SQL_DSN="postgresql://<db_user>:<db_password>@127.0.0.1:5433/new_api" \
REDIS_CONN_STRING="redis://:<redis_password>@127.0.0.1:6381" \
TZ="Asia/Shanghai" \
BATCH_UPDATE_ENABLED=true \
NODE_TYPE=slave \
go run .

本地调试建议

如果本地连的是共享或生产数据库,建议使用 NODE_TYPE=slave,让本地进程只处理请求,不跑定时任务,避免和服务器主节点重复执行后台任务。

sub2api 本地开发

sub2api 通常直接走远程数据库联调模式。它和 new-api 可以共用同一条 SSH 隧道。

容器模式:

bash
cd ~/Code/kaiyuan/cpa/sub2api
podman compose -f docker-compose.remote-db.yml up -d
podman compose -f docker-compose.remote-db.yml logs -f sub2api

本地 Go 进程模式:

bash
cd ~/Code/kaiyuan/cpa/sub2api/backend

DATABASE_HOST=127.0.0.1 \
DATABASE_PORT=5433 \
DATABASE_USER="<db_user>" \
DATABASE_PASSWORD="<db_password>" \
DATABASE_DBNAME=sub2api \
DATABASE_SSLMODE=disable \
REDIS_HOST=127.0.0.1 \
REDIS_PORT=6381 \
REDIS_PASSWORD="<redis_password>" \
TZ=Asia/Shanghai \
AUTO_SETUP=true \
go run ./cmd/server

前端开发服务器:

bash
cd ~/Code/kaiyuan/cpa/sub2api/frontend
pnpm install
pnpm dev

常用端口:

服务地址
new-api 后端http://localhost:3000
new-api 前端http://localhost:3001
sub2api 后端http://localhost:8080
sub2api 前端http://localhost:5173

生产部署概览

生产环境通常由 Docker/1Panel 管理基础服务:

服务说明
PostgreSQL只监听服务器内网地址
Redis只监听服务器内网地址
OpenResty负责 HTTPS 和反向代理
new-apiAPI 网关与控制台
sub2api独立服务

建议部署流程:

  1. 推送代码到 GitHub fork。
  2. GitHub Actions 构建 linux/arm64 镜像。
  3. 推送镜像到 GHCR。
  4. 服务器拉取新镜像。
  5. 使用 Docker Compose 或 1Panel 重启服务。
  6. 检查健康接口、登录页和关键 API。

域名规划

域名目标
ai.laiber.cloudnew-api 控制台与 API
sub2api.laiber.cloudsub2api 服务
docs.laiber.cloudVitePress 文档站

Cloudflare DNS 中通常添加 ACNAME 记录,并开启 HTTPS。业务服务由服务器反向代理处理,文档站建议直接部署到 Cloudflare Pages。

常用排障命令

bash
# 登录服务器
ssh qianshan-oci

# 查看容器
docker ps

# 查看本地 new-api 日志
podman compose -f docker-compose.dev.yml logs -f new-api

# 查看远程数据库联调容器日志
podman compose -f docker-compose.remote-db.yml logs -f new-api

常见问题

本地后端启动后 localhost:3000 打不开

GoLand 的 Delve 调试端口不是应用端口。应用只有在数据库迁移和初始化完成后才会监听 :3000。如果日志停在数据库迁移阶段,先检查数据库连接、隧道和迁移是否卡住。

可以同时启动两个 master 吗

不建议。master 会跑后台任务和定时任务,本地连共享数据库时容易和服务器重复执行。调试请求链路时优先用 NODE_TYPE=slave

密码显示接口报 cipher: message authentication failed

这通常表示数据库里的加密值不是用当前密钥链加密的。相关环境变量优先级通常是:

text
UPSTREAM_SECRET_KEY > CRYPTO_SECRET > SESSION_SECRET

本地和服务器的密钥不一致时,旧数据可能无法解密,需要确认环境变量一致或重新保存对应密码。

稳定、清晰、方便接入