chore: switch new-api deployment to shared infra

This commit is contained in:
zizi 2026-04-11 22:57:26 +08:00
parent dd0b85213b
commit 67a72f7255
7 changed files with 174 additions and 141 deletions

View File

@ -21,6 +21,10 @@
# 数据库相关配置
# 数据库连接字符串
# SQL_DSN=user:password@tcp(127.0.0.1:3306)/dbname?parseTime=true
# Host process profile on infra host:
# SQL_DSN=postgresql://root:example-password@127.0.0.1:5433/new-api
# Docker profile on same host:
# SQL_DSN=postgresql://root:example-password@infra-postgres:5432/new-api
# 日志数据库连接字符串
# LOG_SQL_DSN=user:password@tcp(127.0.0.1:3306)/logdb?parseTime=true
# SQLite数据库路径
@ -36,6 +40,10 @@
# 缓存相关配置
# Redis连接字符串
# REDIS_CONN_STRING=redis://user:password@localhost:6379/0
# Host process profile on infra host:
# REDIS_CONN_STRING=redis://:example-password@127.0.0.1:6379/0
# Docker profile on same host:
# REDIS_CONN_STRING=redis://:example-password@infra-redis:6379/0
# 同步频率(单位:秒)
# SYNC_FREQUENCY=60
# 内存缓存启用

View File

@ -224,71 +224,52 @@ For request structs that are parsed from client JSON and then re-marshaled to up
- 是上游不通
- 还是服务端计费配置缺失
## 9. 当前线上部署形态2026-04-04 更新)
## 9. 当前目标部署形态2026-04-11 更新)
- 远程服务器仍是:`个人-minione-ubuntu-infra-4c16g120g`
- `new-api` **不再**以 Docker 应用容器运行;当前由宿主机 `systemd` 服务启动
- `new-api` 继续以宿主机 `systemd` 进程运行
- 服务名:`new-api`
- `systemctl is-active new-api` 应返回 `active`
- `systemctl is-enabled new-api` 应返回 `enabled`
- 当前线上运行版本固定为最新稳定 tag
- `v0.11.9`
- 实际部署目录不是 `/root/new-api`,而是单独的源码 worktree
- `/root/new-api-v0.11.9`
- 只管理应用进程,不管理基础设施生命周期
- 远程部署目录应为正常 Git checkout
- 目标目录:`/root/new-api-deploy`
- 关键文件:
- 二进制:`/root/new-api-v0.11.9/new-api`
- 运行环境:`/root/new-api-v0.11.9/.env.runtime`
- 启动脚本:`/root/new-api-v0.11.9/run-new-api.sh`
- 二进制:`/root/new-api-deploy/new-api`
- 运行环境:`/root/new-api-deploy/.env.runtime`
- systemd 单元文件:`/etc/systemd/system/new-api.service`
## 10. 依赖服务与连接方式2026-04-04 更新)
- PostgreSQL 和 Redis 仍然跑在 Docker 中,但**只作为依赖容器**存在,不再承载应用本体。
- 当前容器:
- PostgreSQL`postgres`
- Redis`redis`
- 当前宿主机固定入口:
## 10. 依赖服务与连接方式2026-04-11 更新)
- PostgreSQL 和 Redis 是共享基础设施,不属于 `new-api` 仓库内嵌部署的一部分。
- 宿主机进程模式固定入口:
- PostgreSQL`127.0.0.1:5433`
- Redis`127.0.0.1:6379`
- `new-api` 宿主机进程必须连接宿主机固定入口,不要再依赖容器名或容器 IP
- `SQL_DSN=postgresql://root:123456@127.0.0.1:5433/new-api`
- `REDIS_CONN_STRING=redis://127.0.0.1:6379`
- 原因:
- 容器 IP 会变,写死就是垃圾设计。
- 用宿主机固定入口,重建 PG/Redis 容器时不需要改应用配置。
- 同宿主机 Docker 模式固定入口:
- PostgreSQL`infra-postgres:5432`
- Redis`infra-redis:6379`
- `new-api` 不应再依赖容器 IP也不应再依赖 `postgres` / `redis` 这种应用级旧名字。
## 11. 数据保护与备份2026-04-04 更新)
- PostgreSQL 数据仍保存在 Docker volume
- `new-api_pg_data`
- **不要**删除、重建、覆盖这个 volume除非明确知道自己在做什么。
- 本次切换前已做 PG 备份:
- `/root/backups/new-api/new-api-cutover-20260404-094849.dump`
- 这次切换后已核对关键表仍在:
- `channels=10`
- `abilities=153`
- `options=9`
## 11. 共享数据库事实2026-04-11 更新)
- 当前 PostgreSQL 是共享基础设施,至少同时承载:
- `new-api`
- `gitea`
- 迁移 PostgreSQL 时不要把它当成 `new-api` 独占数据库。
- Redis 目前主要视为共享缓存基础设施。
## 12. 运维入口与排障顺序2026-04-04 更新)
- 现在排障先看 `systemd`,不是先看 Docker 应用容器
## 12. 运维入口与排障顺序2026-04-11 更新)
- `new-api` 排障先看:
- `systemctl status new-api`
- `journalctl -u new-api -n 200 --no-pager`
- `journalctl -u new-api -f`
- 服务健康检查:
- `new-api` 健康检查:
- `curl http://127.0.0.1:3000/api/status`
- 当前线上版本应看到:
- `v0.11.9`
- Docker 现在只需要关心依赖容器是否活着:
- `docker ps | grep -E 'postgres|redis'`
- 不要再默认使用 `/root/new-api/docker-compose.yml` 管理应用本体。
- 这个仓库目录现在主要是源码主仓库,不是实际运行目录。
- 实际运行目录是 `/root/new-api-v0.11.9`
- 基础设施排障再看:
- `docker ps | grep -E 'infra-postgres|infra-redis|gitea'`
- `ss -lntp | grep -E ':5433|:6379|:3000|:3001|:2222'`
- 不要再把仓库里的 `docker-compose.yml` 当成生产真相;它只描述 app-only Docker 运行方式。
## 13. 后续升级原则2026-04-04 更新)
- 升级时优先选择新的**稳定 tag**,不要直接拿 `main``latest` 当生产版本
- 合理流程应该是
1. 为目标稳定 tag 建单独部署目录或 worktree
2. 编译产出新二进制
3. 保留 PG volume不迁移数据库文件路径
4. 让 systemd 指向新版本
## 13. 后续升级原则2026-04-11 更新)
- 远程升级以 Git 可拉取 checkout 为前提,不再使用 detached tag worktree 作为长期部署形态。
- 合理流程:
1. `/root/new-api-deploy` 拉取最新目标分支
2. 编译新二进制
3. 确认共享 PostgreSQL / Redis 健康
4. `systemd` 重启 `new-api`
5. 验证 `api/status`、日志、数据库连接再收尾
- 如果有人再次看到 `docker-compose.yml` 里定义了 `new-api` 服务,不要想当然地认定线上还在用容器跑应用;先查:
- `systemctl status new-api`
- `ss -lntp | grep :3000`

View File

@ -106,18 +106,37 @@
## 🚀 Quick Start
### Using Docker Compose (Recommended)
### Using Docker Compose
```bash
# Clone the project
git clone https://github.com/QuantumNous/new-api.git
cd new-api
# Edit docker-compose.yml configuration
nano docker-compose.yml
# Copy environment template
cp .env.example .env.runtime
# Edit SQL_DSN and REDIS_CONN_STRING for your runtime profile
nano .env.runtime
# Start the service
docker-compose up -d
docker compose --env-file .env.runtime up -d
```
This compose file is app-only. PostgreSQL and Redis are expected to be external shared infrastructure.
Host process profile on the infra host:
```bash
SQL_DSN=postgresql://root:${POSTGRES_PASSWORD}@127.0.0.1:5433/new-api
REDIS_CONN_STRING=redis://:${REDIS_PASSWORD}@127.0.0.1:6379/0
```
Docker profile on the same host:
```bash
SQL_DSN=postgresql://root:${POSTGRES_PASSWORD}@infra-postgres:5432/new-api
REDIS_CONN_STRING=redis://:${REDIS_PASSWORD}@infra-redis:6379/0
```
<details>
@ -310,8 +329,8 @@ docker run --name new-api -d --restart always \
|--------|------|--------|
| `SESSION_SECRET` | Session secret (required for multi-machine deployment) | - |
| `CRYPTO_SECRET` | Encryption secret (required for Redis) | - |
| `SQL_DSN` | Database connection string | - |
| `REDIS_CONN_STRING` | Redis connection string | - |
| `SQL_DSN` | Database connection string. Use `127.0.0.1:5433` for host mode or `infra-postgres:5432` for same-host Docker mode | - |
| `REDIS_CONN_STRING` | Redis connection string. Use `127.0.0.1:6379` for host mode or `infra-redis:6379` for same-host Docker mode | - |
| `STREAMING_TIMEOUT` | Streaming timeout (seconds) | `300` |
| `STREAM_SCANNER_MAX_BUFFER_MB` | Max per-line buffer (MB) for the stream scanner; increase when upstream sends huge image/base64 payloads | `64` |
| `MAX_REQUEST_BODY_MB` | Max request body size (MB, counted **after decompression**; prevents huge requests/zip bombs from exhausting memory). Exceeding it returns `413` | `32` |

View File

@ -106,18 +106,37 @@
## 🚀 快速开始
### 使用 Docker Compose(推荐)
### 使用 Docker Compose
```bash
# 克隆项目
git clone https://github.com/QuantumNous/new-api.git
cd new-api
# 编辑 docker-compose.yml 配置
nano docker-compose.yml
# 复制环境变量模板
cp .env.example .env.runtime
# 按运行模式填写 SQL_DSN 和 REDIS_CONN_STRING
nano .env.runtime
# 启动服务
docker-compose up -d
docker compose --env-file .env.runtime up -d
```
当前 `docker-compose.yml` 只负责应用本体PostgreSQL 和 Redis 应作为外部共享基础设施提供。
宿主机进程模式:
```bash
SQL_DSN=postgresql://root:${POSTGRES_PASSWORD}@127.0.0.1:5433/new-api
REDIS_CONN_STRING=redis://:${REDIS_PASSWORD}@127.0.0.1:6379/0
```
同宿主机 Docker 模式:
```bash
SQL_DSN=postgresql://root:${POSTGRES_PASSWORD}@infra-postgres:5432/new-api
REDIS_CONN_STRING=redis://:${REDIS_PASSWORD}@infra-redis:6379/0
```
<details>
@ -310,8 +329,8 @@ docker run --name new-api -d --restart always \
|--------|--------------------------------------------------------------|--------|
| `SESSION_SECRET` | 会话密钥(多机部署必须) | - |
| `CRYPTO_SECRET` | 加密密钥Redis 必须) | - |
| `SQL_DSN` | 数据库连接字符串 | - |
| `REDIS_CONN_STRING` | Redis 连接字符串 | - |
| `SQL_DSN` | 数据库连接字符串。宿主机模式使用 `127.0.0.1:5433`,同宿主机 Docker 模式使用 `infra-postgres:5432` | - |
| `REDIS_CONN_STRING` | Redis 连接字符串。宿主机模式使用 `127.0.0.1:6379`,同宿主机 Docker 模式使用 `infra-redis:6379` | - |
| `STREAMING_TIMEOUT` | 流式超时时间(秒) | `300` |
| `STREAM_SCANNER_MAX_BUFFER_MB` | 流式扫描器单行最大缓冲MB图像生成等超大 `data:` 片段(如 4K 图片 base64需适当调大 | `64` |
| `MAX_REQUEST_BODY_MB` | 请求体最大大小MB**解压后**计;防止超大请求/zip bomb 导致内存暴涨),超过将返回 `413` | `32` |

View File

@ -1,19 +1,3 @@
# New-API Docker Compose Configuration
#
# Quick Start:
# 1. docker-compose up -d
# 2. Access at http://localhost:3000
#
# Using MySQL instead of PostgreSQL:
# 1. Comment out the postgres service and SQL_DSN line 15
# 2. Uncomment the mysql service and SQL_DSN line 16
# 3. Uncomment mysql in depends_on (line 28)
# 4. Uncomment mysql_data in volumes section (line 64)
#
# ⚠️ IMPORTANT: Change all default passwords before deploying to production!
version: '3.4' # For compatibility with older Docker versions
services:
new-api:
image: calciumion/new-api:latest
@ -26,71 +10,21 @@ services:
- ./data:/data
- ./logs:/app/logs
environment:
- SQL_DSN=postgresql://root:123456@postgres:5432/new-api # ⚠️ IMPORTANT: Change the password in production!
# - SQL_DSN=root:123456@tcp(mysql:3306)/new-api # Point to the mysql service, uncomment if using MySQL
- REDIS_CONN_STRING=redis://redis
- TZ=Asia/Shanghai
- ERROR_LOG_ENABLED=true # 是否启用错误日志记录 (Whether to enable error log recording)
- BATCH_UPDATE_ENABLED=true # 是否启用批量更新 (Whether to enable batch update)
# - STREAMING_TIMEOUT=300 # 流模式无响应超时时间单位秒默认120秒如果出现空补全可以尝试改为更大值 Streaming timeout in seconds, default is 120s. Increase if experiencing empty completions
# - SESSION_SECRET=random_string # 多机部署时设置,必须修改这个随机字符串!! multi-node deployment, set this to a random string!!!!!!!
# - SYNC_FREQUENCY=60 # Uncomment if regular database syncing is needed
# - GOOGLE_ANALYTICS_ID=G-XXXXXXXXXX # Google Analytics 的测量 ID (Google Analytics Measurement ID)
# - UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Umami 网站 ID (Umami Website ID)
# - UMAMI_SCRIPT_URL=https://analytics.umami.is/script.js # Umami 脚本 URL默认为官方地址 (Umami Script URL, defaults to official URL)
depends_on:
- redis
- postgres
# - mysql # Uncomment if using MySQL
SQL_DSN: ${SQL_DSN:?SQL_DSN is required}
REDIS_CONN_STRING: ${REDIS_CONN_STRING:?REDIS_CONN_STRING is required}
TZ: ${TZ:-Asia/Shanghai}
ERROR_LOG_ENABLED: ${ERROR_LOG_ENABLED:-true}
BATCH_UPDATE_ENABLED: ${BATCH_UPDATE_ENABLED:-true}
networks:
- new-api-network
- default
- infra-shared
healthcheck:
test: ["CMD-SHELL", "wget -q -O - http://localhost:3000/api/status | grep -o '\"success\":\\s*true' || exit 1"]
interval: 30s
timeout: 10s
retries: 3
redis:
image: redis:latest
container_name: redis
restart: always
networks:
- new-api-network
postgres:
image: postgres:15
container_name: postgres
restart: always
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: 123456 # ⚠️ IMPORTANT: Change this password in production!
POSTGRES_DB: new-api
volumes:
- pg_data:/var/lib/postgresql/data
networks:
- new-api-network
# ports:
# - "5432:5432" # Uncomment if you need to access PostgreSQL from outside Docker
# mysql:
# image: mysql:8.2
# container_name: mysql
# restart: always
# environment:
# MYSQL_ROOT_PASSWORD: 123456 # ⚠️ IMPORTANT: Change this password in production!
# MYSQL_DATABASE: new-api
# volumes:
# - mysql_data:/var/lib/mysql
# networks:
# - new-api-network
# ports:
# - "3306:3306" # Uncomment if you need to access MySQL from outside Docker
volumes:
pg_data:
# mysql_data:
networks:
new-api-network:
driver: bridge
infra-shared:
external: true
name: infra-shared

9
ops/remote/README.md Normal file
View File

@ -0,0 +1,9 @@
# Remote Runtime Notes
这个目录记录远程主机运行事实,避免把主机级流水账继续堆回根文档。
约定:
- 一台主机一份 `*.AGENT.md`
- 只写运行事实、入口、路径、端口、依赖和排障命令
- 项目规则仍放在根 `AGENTS.md` / `CLAUDE.md`

View File

@ -0,0 +1,63 @@
# Remote Host AGENT — minione-ubuntu-infra-4c16g120g
## Host Identity
- Host name: `minione-ubuntu-infra`
- Tailscale IP: `100.64.0.11`
- LAN IP: `192.168.1.3`
- Access profile: `个人-minione-ubuntu-infra-4c16g120g`
## Runtime Topology
- `new-api` runs as a host `systemd` process
- `gitea` runs in Docker Compose under `/opt/gitea`
- PostgreSQL and Redis run as shared Docker infrastructure
- Shared Docker network: `infra-shared`
## Shared Infrastructure
### PostgreSQL
- Container name: `infra-postgres`
- Host port: `127.0.0.1:5433`
- Docker alias: `infra-postgres:5432`
- Databases:
- `new-api`
- `gitea`
- Data path: `/srv/infra/postgres/data`
- Backup path: `/srv/infra/postgres/backup`
### Redis
- Container name: `infra-redis`
- Host port: `127.0.0.1:6379`
- Docker alias: `infra-redis:6379`
- Data path: `/srv/infra/redis/data`
## new-api
- Service name: `new-api`
- Deploy path: `/root/new-api-deploy`
- Runtime env: `/root/new-api-deploy/.env.runtime`
- systemd unit: `/etc/systemd/system/new-api.service`
- Health check: `curl --noproxy '*' http://127.0.0.1:3000/api/status`
Host-process connection profile:
- `SQL_DSN=postgresql://root:<password>@127.0.0.1:5433/new-api`
- `REDIS_CONN_STRING=redis://:<password>@127.0.0.1:6379/0`
## gitea
- Compose path: `/opt/gitea/docker-compose.yml`
- Config path: `/opt/gitea/data/gitea/conf/app.ini`
- Web: `http://100.64.0.11:3001/`
- SSH: `ssh -p 2222 git@100.64.0.11`
- Database host: `infra-postgres:5432`
## Routine Checks
- `systemctl status new-api`
- `journalctl -u new-api -n 200 --no-pager`
- `docker ps --format '{{.Names}} | {{.Image}} | {{.Ports}}'`
- `ss -lntp | egrep ':3000|:3001|:2222|:5433|:6379'`