Skip to content

new-api and sub2api Local Development and Deployment

This page is for maintainers. It summarizes local development, remote database debugging, and production deployment workflows for new-api and sub2api.

Security

Do not commit production database passwords, Redis passwords, SSH keys, panel URLs, or real server IPs to a public repository. This page uses placeholders. Read actual values from your password manager, server environment, or 1Panel app configuration.

Repositories

ProjectUpstreamFork
new-apihttps://github.com/QuantumNous/new-apihttps://github.com/2Red1Blue/new-api
sub2apihttps://github.com/mansebia/sub2apihttps://github.com/2Red1Blue/sub2api

Suggested local paths:

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

Git remote strategy

origin points to your fork for custom changes. upstream points to the official project for updates.

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

You can use rebase for a cleaner history, but avoid rewriting shared branch history unless you know the impact.

new-api local full stack

new-api includes a development compose file with backend, PostgreSQL, and Redis.

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

Backend:

text
http://localhost:3000

Rebuild after Go changes:

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

Stop:

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

Reset local data:

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

Frontend dev server:

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

The frontend usually runs at http://localhost:3001 and proxies API requests to :3000.

Remote database debugging

When real server data is required, use an SSH tunnel to map server-side PostgreSQL and Redis to local ports.

text
local 5433 -> SSH tunnel -> server 127.0.0.1:5432 PostgreSQL
local 6381 -> SSH tunnel -> server 127.0.0.1:6379 Redis

Create the tunnel:

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

Check ports:

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

Debug new-api with remote DB

Container mode:

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

Native Go process mode is better for GoLand or VS Code breakpoints. Prepare placeholder frontend files first because the backend embeds frontend build output:

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

Start the backend:

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 .

Local debugging

When connecting a local process to a shared or production database, prefer NODE_TYPE=slave. It handles requests but does not run scheduled background tasks, reducing the chance of duplicate work with the server master node.

sub2api local development

sub2api usually uses the remote database mode and can share the same SSH tunnel.

Container mode:

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

Native Go process:

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

Frontend:

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

Common ports:

ServiceURL
new-api backendhttp://localhost:3000
new-api frontendhttp://localhost:3001
sub2api backendhttp://localhost:8080
sub2api frontendhttp://localhost:5173

Production deployment overview

Production typically uses Docker and 1Panel:

ServicePurpose
PostgreSQLInternal database
RedisInternal cache
OpenRestyHTTPS and reverse proxy
new-apiAPI gateway and console
sub2apiIndependent service

Suggested deployment flow:

  1. Push code to the GitHub fork.
  2. Build a linux/arm64 image with GitHub Actions.
  3. Push the image to GHCR.
  4. Pull the image on the server.
  5. Restart services with Docker Compose or 1Panel.
  6. Check health endpoints, sign-in page, and critical APIs.

Domain plan

DomainTarget
ai.laiber.cloudnew-api console and API
sub2api.laiber.cloudsub2api
docs.laiber.cloudVitePress docs on Cloudflare Pages

Business services are usually handled by server reverse proxy. The docs site should be deployed directly to Cloudflare Pages.

Common commands

bash
# SSH into the server
ssh qianshan-oci

# List containers
docker ps

# Local new-api logs
podman compose -f docker-compose.dev.yml logs -f new-api

# Remote DB debug logs
podman compose -f docker-compose.remote-db.yml logs -f new-api

FAQ

localhost:3000 does not open after starting the backend

The Delve port from GoLand is not the app port. The app listens on :3000 only after database migration and initialization finish. If logs are stuck at migration, check database connectivity, SSH tunnel, and migration status.

Can two master nodes run at the same time?

Not recommended. A master runs background and scheduled tasks. When debugging against a shared database, use NODE_TYPE=slave.

Password reveal returns cipher: message authentication failed

This usually means encrypted database values were not encrypted with the current key chain. The typical priority is:

text
UPSTREAM_SECRET_KEY > CRYPTO_SECRET > SESSION_SECRET

If local and server keys differ, old encrypted values may not decrypt. Align environment variables or resave the password.

Stable, clear, and easy to connect