From e6bced5dc2cc56a5f1ea5780aa9fc7926eaffa0d Mon Sep 17 00:00:00 2001 From: zizi Date: Mon, 18 May 2026 23:39:31 +0800 Subject: [PATCH] chore: rebuild dev/1.0.0 from main with docs and deploy config - Rebase dev/1.0.0 on latest upstream main (drop Muse relay code) - Preserve: troubleshooting records, remote layout, Docker deploy workflow - Simplify docker-compose.yml to app-only (external PG/Redis) - Add ops/remote/ host documentation - Update .env.example with host/docker connection profiles --- .env.example | 10 +- AGENTS.md | 17 + CLAUDE.md | 56 +++ README.md | 69 ++-- README.zh_CN.md | 61 +-- docker-compose.yml | 88 +---- ops/remote/GIT_GITEA.AGENT.md | 363 ++++++++++++++++++ ops/remote/README.md | 9 + ops/remote/TEMPLATE.AGENT.md | 73 ++++ .../minione-ubuntu-infra-4c16g120g.AGENT.md | 63 +++ 10 files changed, 675 insertions(+), 134 deletions(-) create mode 100644 ops/remote/GIT_GITEA.AGENT.md create mode 100644 ops/remote/README.md create mode 100644 ops/remote/TEMPLATE.AGENT.md create mode 100644 ops/remote/minione-ubuntu-infra-4c16g120g.AGENT.md diff --git a/.env.example b/.env.example index b152c2a1..72675aa2 100644 --- a/.env.example +++ b/.env.example @@ -19,10 +19,12 @@ # HOSTNAME=your-hostname # 数据库相关配置 -# 启用错误日志记录 -# ERROR_LOG_ENABLED=true # 数据库连接字符串 # 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数据库路径 @@ -38,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 # 内存缓存启用 diff --git a/AGENTS.md b/AGENTS.md index c18b5e32..20d7dc9c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -135,3 +135,20 @@ For request structs that are parsed from client JSON and then re-marshaled to up ### Rule 7: Billing Expression System — Read `pkg/billingexpr/expr.md` When working on tiered/dynamic billing (expression-based pricing), you MUST read `pkg/billingexpr/expr.md` first. It documents the design philosophy, expression language (variables, functions, examples), full system architecture (editor → storage → pre-consume → settlement → log display), token normalization rules (`p`/`c` auto-exclusion), quota conversion, and expression versioning. All code changes to the billing expression system must follow the patterns described in that document. + + +# 项目运维与排障 + +排障记录、远程布局、部署流程详见 `CLAUDE.md` 底部"项目排障记录"章节。 + +## Git 远程角色布局 + +| 远程 | URL | 角色 | +|------|-----|------| +| `upstream` | `https://github.com/QuantumNous/new-api.git` | 官方上游(只读) | +| `gitea` | `ssh://git@100.64.0.8:2222/admin/new-api-dev.git` | 读-only 开发镜像 | +| `ea-ali` | `ssh://git@101.200.34.71:2222/zizi-al/new-api.git` | 可写开发远程(默认 push) | + +## 远程运行事实入口 + +具体远程部署、主机拓扑、端口、备份、Gitea 运行方式等,统一收口到 `ops/remote/` 下对应主机文档。不要往项目根文档追加主机级流水账。 diff --git a/CLAUDE.md b/CLAUDE.md index 4b084154..de84aa07 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -135,3 +135,59 @@ For request structs that are parsed from client JSON and then re-marshaled to up ### Rule 7: Billing Expression System — Read `pkg/billingexpr/expr.md` When working on tiered/dynamic billing (expression-based pricing), you MUST read `pkg/billingexpr/expr.md` first. It documents the design philosophy, expression language (variables, functions, examples), full system architecture (editor → storage → pre-consume → settlement → log display), token normalization rules (`p`/`c` auto-exclusion), quota conversion, and expression versioning. All code changes to the billing expression system must follow the patterns described in that document. + + +# new-api 项目排障记录 + +## 排障原则 +- 不要先改 Docker 配置,先查数据库表:`channels`、`abilities`、`options` +- 不要因为代码默认值存在,就假定线上有效 +- 遇到"倍率或价格未配置"时,优先检查:`options.ModelRatio`、`options.ModelPrice` +- 遇到渠道测试失败时,先分清:上游不通 vs 服务端计费配置缺失 +- 代码里有默认倍率,但线上运行时会被数据库 `options.ModelRatio` 覆盖 +- `new-api` 会定时从数据库同步 `options` 和 `channels`,不需要每次重启;日志关键字:`syncing options from database` + +## 依赖服务与连接方式 +- PostgreSQL 和 Redis 是共享基础设施,不属于 `new-api` 仓库内嵌部署的一部分 +- 宿主机进程模式固定入口:PostgreSQL `127.0.0.1:5433`、Redis `127.0.0.1:6379` +- 同宿主机 Docker 模式固定入口:PostgreSQL `infra-postgres:5432`、Redis `infra-redis:6379` + +## 运维入口与排障顺序 +- `new-api` 健康检查:`curl http://127.0.0.1:3000/api/status` +- 基础设施排障:`docker ps | grep -E 'infra-postgres|infra-redis|gitea'` + +## Git 远程角色布局(2026-05-18 更新) + +| 远程 | URL | 角色 | 备注 | +|------|-----|------|------| +| `upstream` | `https://github.com/QuantumNous/new-api.git` | 官方上游 | 只读,fetch only | +| `gitea` | `ssh://git@100.64.0.8:2222/admin/new-api-dev.git` | 读-only 开发镜像 | push 已禁用(`no-push`) | +| `ea-ali` | `ssh://git@101.200.34.71:2222/zizi-al/new-api.git` | 可写开发远程 | `remote.pushDefault` 指向此 | + +代码流向:`upstream` → 本地 → `gitea`(镜像同步)→ 本地 → `ea-ali`(二开推送) + +- `ea-ali` 服务器无法访问 `100.64.0.8`,同步必须经本地中转 +- 当前开发分支:`dev/1.0.0`,跟踪 `ea-ali/dev/1.0.0` + +## 本地编译 Docker 部署流程(2026-05-18 新增) + +本地开发 → 本地 Docker 构建 → 上传镜像 → 远程 Docker 部署。 + +```bash +# 1. 本地构建 +docker build -t new-api:local . + +# 2. 导出 +docker save new-api:local | gzip > /tmp/new-api-local.tar.gz + +# 3. 上传到远程 +scp /tmp/new-api-local.tar.gz root@:/tmp/ + +# 4. 远程加载 +ssh root@ "docker load < /tmp/new-api-local.tar.gz" + +# 5. 远程重启 +ssh root@ "cd /opt/new-api && docker compose up -d" +``` + +镜像 tag 建议带版本号:`new-api:1.0.0-dev`、`new-api:1.0.0-rc1`。 diff --git a/README.md b/README.md index ab6f1499..4896cdb7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
-![new-api](/web/default/public/logo.png) +![new-api](/web/public/logo.png) # New API @@ -55,10 +55,9 @@ ## 📝 Project Description > [!IMPORTANT] -> - This project is intended solely for lawful and authorized AI API gateway, organization-level authentication, multi-model management, usage analytics, cost accounting, and private deployment scenarios. -> - Users must lawfully obtain upstream API keys, accounts, model services, and interface permissions, and must comply with upstream terms of service and applicable laws and regulations. -> - Users should ensure their use complies with upstream terms of service and applicable laws and regulations. -> - When providing generative AI services to the public, users should comply with applicable regulatory requirements and fulfill all filing, licensing, content safety, real-name verification, log retention, tax, and upstream authorization obligations required by their jurisdiction. +> - This project is for personal learning purposes only, with no guarantee of stability or technical support +> - Users must comply with OpenAI's [Terms of Use](https://openai.com/policies/terms-of-use) and **applicable laws and regulations**, and must not use it for illegal purposes +> - According to the [《Interim Measures for the Management of Generative Artificial Intelligence Services》](http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm), please do not provide any unregistered generative AI services to the public in China. --- @@ -107,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 ```
@@ -152,9 +170,6 @@ docker run --name new-api -d --restart always \ 🎉 After deployment is complete, visit `http://localhost:3000` to start using! -> [!WARNING] -> When operating this project as a public generative AI service or API resale service, users should first complete all required filing, licensing, content safety, real-name verification, log retention, tax, payment, and upstream authorization obligations. - 📖 For more deployment methods, please refer to [Deployment Guide](https://docs.newapi.pro/en/docs/installation) --- @@ -193,12 +208,12 @@ docker run --name new-api -d --restart always \ | 📈 Data Dashboard | Visual console and statistical analysis | | 🔒 Permission Management | Token grouping, model restrictions, user management | -### 💰 Authorized Usage Accounting and Billing +### 💰 Payment and Billing -- ✅ Internal top-up and quota allocation for lawful authorized scenarios (EPay, Stripe) -- ✅ Organization-level per-request, usage-based, and cache-hit cost accounting -- ✅ Cache billing statistics for OpenAI, Azure, DeepSeek, Claude, Qwen, and supported models -- ✅ Flexible billing policies for internal management or authorized enterprise customers +- ✅ Online recharge (EPay, Stripe) +- ✅ Pay-per-use model pricing +- ✅ Cache billing support (OpenAI, Azure, DeepSeek, Claude, Qwen and all supported models) +- ✅ Flexible billing policy configuration ### 🔐 Authorization and Security @@ -206,7 +221,7 @@ docker run --name new-api -d --restart always \ - 🤖 LinuxDO authorization login - 📱 Telegram authorization login - 🔑 OIDC unified authentication -- 🔍 Key quota query usage (with [new-api-key-tool](https://github.com/Calcium-Ion/new-api-key-tool)) +- 🔍 Key quota query usage (with [neko-api-key-tool](https://github.com/Calcium-Ion/neko-api-key-tool)) ### 🚀 Advanced Features @@ -258,7 +273,7 @@ docker run --name new-api -d --restart always \ ## 🤖 Model Support -> For details, please refer to [API Documentation - Gateway Interface](https://docs.newapi.pro/en/docs/api) +> For details, please refer to [API Documentation - Relay Interface](https://docs.newapi.pro/en/docs/api) | Model Type | Description | Documentation | |---------|------|------| @@ -270,7 +285,7 @@ docker run --name new-api -d --restart always \ | 💬 Claude | Messages format | [Documentation](https://docs.newapi.pro/en/docs/api/ai-model/chat/createmessage) | | 🌐 Gemini | Google Gemini format | [Documentation](https://docs.newapi.pro/en/docs/api/ai-model/chat/gemini/geminirelayv1beta) | | 🔧 Dify | ChatFlow mode | - | -| 🎯 Custom upstream | Supports configuring legally authorized upstream endpoints | - | +| 🎯 Custom | Supports complete call address | - | ### 📡 Supported Interfaces @@ -314,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` | @@ -420,7 +435,7 @@ docker run --name new-api -d --restart always \ | Project | Description | |------|------| -| [new-api-key-tool](https://github.com/Calcium-Ion/new-api-key-tool) | Key quota query tool | +| [neko-api-key-tool](https://github.com/Calcium-Ion/neko-api-key-tool) | Key quota query tool | | [new-api-horizon](https://github.com/Calcium-Ion/new-api-horizon) | New API high-performance optimized version | --- @@ -451,14 +466,6 @@ Welcome all forms of contribution! This project is licensed under the [GNU Affero General Public License v3.0 (AGPLv3)](./LICENSE). -Additional terms under AGPLv3 Section 7 apply. Modified versions must preserve -the author attribution notice `Frontend design and development by New API -contributors.` in the appropriate legal notices and in any prominent about, -legal, footer, or attribution location presented by the user interface. - -Modified versions that present a user interface must also preserve a visible -link to the original project: . - This is an open-source project developed based on [One API](https://github.com/songquanpeng/one-api) (MIT License). If your organization's policies do not permit the use of AGPLv3-licensed software, or if you wish to avoid the open-source obligations of AGPLv3, please contact us at: [support@quantumnous.com](mailto:support@quantumnous.com) diff --git a/README.zh_CN.md b/README.zh_CN.md index 1e3f5f68..5ac04e8d 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -1,6 +1,6 @@
-![new-api](/web/default/public/logo.png) +![new-api](/web/public/logo.png) # New API @@ -55,10 +55,9 @@ ## 📝 项目说明 > [!IMPORTANT] -> - 本项目仅面向合法授权的 AI API 网关、组织内部鉴权、多模型管理、用量统计、成本核算和私有化部署场景。 -> - 使用者必须合法取得上游 API Key、账号、模型服务或接口权限,并遵守上游服务条款及适用法律法规。 -> - 使用者应确保其使用方式符合上游服务条款及适用法律法规。 -> - 面向公众提供生成式人工智能服务时,使用者应遵守[《生成式人工智能服务管理暂行办法》](http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm)等监管要求,自行完成所在司法辖区要求的备案、许可、内容安全、实名、日志留存、税务和上游授权等合规义务。 +> - 本项目仅供个人学习使用,不保证稳定性,且不提供任何技术支持 +> - 使用者必须在遵循 OpenAI 的 [使用条款](https://openai.com/policies/terms-of-use) 以及**法律法规**的情况下使用,不得用于非法用途 +> - 根据 [《生成式人工智能服务管理暂行办法》](http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm) 的要求,请勿对中国地区公众提供一切未经备案的生成式人工智能服务 --- @@ -107,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 ```
@@ -152,9 +170,6 @@ docker run --name new-api -d --restart always \ 🎉 部署完成后,访问 `http://localhost:3000` 即可使用! -> [!WARNING] -> 将本项目作为面向公众的生成式 AI 服务或 API 转售服务运营时,使用者应先完成备案、内容安全、实名、日志留存、税务、支付和上游授权等合规义务。 - 📖 更多部署方式请参考 [部署指南](https://docs.newapi.pro/zh/docs/installation) --- @@ -193,12 +208,12 @@ docker run --name new-api -d --restart always \ | 📈 数据看板 | 可视化控制台与统计分析 | | 🔒 权限管理 | 令牌分组、模型限制、用户管理 | -### 💰 授权用量与成本管理 +### 💰 支付与计费 -- ✅ 合法授权场景下的内部充值与额度分配(易支付、Stripe) -- ✅ 组织内按次、按量或缓存命中成本核算 -- ✅ 支持 OpenAI、Azure、DeepSeek、Claude、Qwen 等模型的缓存计费统计 -- ✅ 面向内部管理或企业客户的灵活计费策略配置 +- ✅ 在线充值(易支付、Stripe) +- ✅ 模型按次数收费 +- ✅ 缓存计费支持(OpenAI、Azure、DeepSeek、Claude、Qwen等所有支持的模型) +- ✅ 灵活的计费策略配置 ### 🔐 授权与安全 @@ -206,7 +221,7 @@ docker run --name new-api -d --restart always \ - 🤖 LinuxDO 授权登录 - 📱 Telegram 授权登录 - 🔑 OIDC 统一认证 -- 🔍 Key 查询使用额度(配合 [new-api-key-tool](https://github.com/Calcium-Ion/new-api-key-tool)) +- 🔍 Key 查询使用额度(配合 [neko-api-key-tool](https://github.com/Calcium-Ion/neko-api-key-tool)) ### 🚀 高级功能 @@ -258,7 +273,7 @@ docker run --name new-api -d --restart always \ ## 🤖 模型支持 -> 详情请参考 [接口文档 - 网关接口](https://docs.newapi.pro/zh/docs/api) +> 详情请参考 [接口文档 - 中继接口](https://docs.newapi.pro/zh/docs/api) | 模型类型 | 说明 | 文档 | |---------|------|------| @@ -270,7 +285,7 @@ docker run --name new-api -d --restart always \ | 💬 Claude | Messages 格式 | [文档](https://docs.newapi.pro/zh/docs/api/ai-model/chat/createmessage) | | 🌐 Gemini | Google Gemini 格式 | [文档](https://docs.newapi.pro/zh/docs/api/ai-model/chat/gemini/geminirelayv1beta) | | 🔧 Dify | ChatFlow 模式 | - | -| 🎯 自定义上游 | 支持配置合法授权的上游接口地址 | - | +| 🎯 自定义 | 支持完整调用地址 | - | ### 📡 支持的接口 @@ -314,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` | @@ -420,7 +435,7 @@ docker run --name new-api -d --restart always \ | 项目 | 说明 | |------|------| -| [new-api-key-tool](https://github.com/Calcium-Ion/new-api-key-tool) | Key 额度查询工具 | +| [neko-api-key-tool](https://github.com/Calcium-Ion/neko-api-key-tool) | Key 额度查询工具 | | [new-api-horizon](https://github.com/Calcium-Ion/new-api-horizon) | New API 高性能优化版 | --- diff --git a/docker-compose.yml b/docker-compose.yml index be8c885b..83775ee6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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,73 +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://:123456@redis:6379 # ⚠️ IMPORTANT: Change the password in production! - - TZ=Asia/Shanghai - - ERROR_LOG_ENABLED=true # 是否启用错误日志记录 (Whether to enable error log recording) - - BATCH_UPDATE_ENABLED=true # 是否启用批量更新 (Whether to enable batch update) - - NODE_NAME=new-api-node-1 # 节点名称,用于审计日志中标识节点身份;多节点/容器部署时建议设置 (Node name used in audit logs; recommended when running multiple instances or in containers) -# - 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 - command: ["redis-server", "--requirepass", "123456"] # ⚠️ IMPORTANT: Change this password in production! - 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 diff --git a/ops/remote/GIT_GITEA.AGENT.md b/ops/remote/GIT_GITEA.AGENT.md new file mode 100644 index 00000000..b250180d --- /dev/null +++ b/ops/remote/GIT_GITEA.AGENT.md @@ -0,0 +1,363 @@ +# Git and Gitea Management AGENT + +## Purpose + +This document defines the canonical workflow for managing: + +- local Git repositories +- GitHub upstream repositories +- writable Gitea repositories +- read-only Gitea mirror repositories + +This file exists to prevent remote confusion, mirror misuse, and branch history corruption. + +## 1. Core Principles + +### 1.1 One repo, one role +Do not let a single remote repository play multiple conflicting roles. + +A repository should be clearly one of: + +- upstream source +- writable development remote +- read-only mirror + +If a repository is a mirror, treat it as a mirror. +If a repository is writable, treat it as writable. +Do not mix the two. + +### 1.2 Never confuse source of truth +The source of truth for official upstream code is the upstream repository, not the writable Gitea dev repo, and not the mirror. + +### 1.3 Keep `main` clean +`main` is for syncing upstream only. +Do not pile local feature work directly into `main`. + +### 1.4 Local changes belong on dev branches +Local work belongs on branches like: + +- `home` +- `feature/*` +- `fix/*` + +Do not treat the mirror repo as a development target. + +## 2. Remote Roles + +### 2.1 Canonical remote names +Use these exact names: + +- `upstream` — official upstream source repository +- `gitea` — writable development repository on Gitea + +Do not rename them casually. + +### 2.2 Role definitions + +#### `upstream` +Used only for: + +- fetching latest official code +- comparing branch divergence +- updating local `main` + +Example: + +- `upstream -> https://github.com/QuantumNous/new-api.git` + +#### `gitea` +Used only for: + +- pushing local branches +- opening PRs on writable Gitea repos +- storing development work + +Example: + +- `gitea -> ssh://git@100.64.0.8:2222/admin/new-api-dev.git` + +#### Read-only mirror repo +If a Gitea repo is configured as a pull mirror, it is read-only for development purposes. + +Example: + +- `admin/new-api` is a pull mirror of GitHub +- it is for sync / reference / backup +- it is not the target for normal pushes + +Do not point `gitea` to a mirror repo. + +## 3. Required Repository Topology + +For projects that track an open-source upstream and also need private or self-hosted development: + +- one upstream repo +- one writable Gitea dev repo +- optional one Gitea mirror repo + +Recommended shape: + +- `upstream` -> official GitHub repo +- `gitea` -> writable Gitea repo +- optional mirror repo exists separately but is not the main local push target + +## 4. Branch Responsibilities + +### `main` +Responsibilities: + +- track upstream +- remain linear and clean +- only accept upstream sync commits or fast-forward updates + +Rules: + +- do not do feature development directly on `main` +- do not use `main` as a scratch branch +- prefer `merge --ff-only` when updating from upstream + +### `home` +Responsibilities: + +- personal development branch +- local operational or infrastructure work +- custom changes that do not belong on clean upstream `main` + +Rules: + +- rebase or merge onto updated `main` +- push to writable Gitea repo +- do not track upstream directly + +### `feature/*` +Responsibilities: + +- isolated work branches +- short-lived development branches +- branch off from current `main` or from `home` when appropriate + +## 5. Standard Workflow + +### 5.1 Inspect repository state +Always inspect first: + +```bash +git remote -v +git branch -vv +git status --short +``` + +If remotes or tracking look wrong, fix them before pushing. + +### 5.2 Sync local `main` with upstream +Preferred flow: + +```bash +git fetch upstream +git switch main +git merge --ff-only upstream/main +git push gitea main +``` + +This keeps: + +- local `main` +- writable Gitea `main` + +aligned with upstream. + +### 5.3 Update development branch after upstream sync +If using rebase: + +```bash +git switch home +git rebase main +git push --force-with-lease gitea home +``` + +If using merge: + +```bash +git switch home +git merge main +git push gitea home +``` + +Use `rebase` when clean linear history matters. +Use `merge` when you do not want history rewriting. + +### 5.4 Create a new working branch +From updated `main`: + +```bash +git switch main +git switch -c feature/ +``` + +Push it: + +```bash +git push -u gitea feature/ +``` + +### 5.5 Push local changes +Always push to writable Gitea repo: + +```bash +git push gitea +``` + +Do not push to mirror repos. + +## 6. Fallback Workflow When GitHub Is Unreachable + +If local machine cannot access GitHub, but the Gitea mirror is confirmed fresh, the mirror may be used as a temporary fetch source. + +Example: + +```bash +git fetch ssh://git@100.64.0.8:2222/admin/new-api.git refs/heads/main:refs/remotes/upstream/main +git switch main +git merge --ff-only upstream/main +git push gitea main +``` + +### Important restriction +Do this only after verifying that the mirror really matches upstream. + +Check both sides: + +- GitHub main commit +- Gitea mirror main commit + +If they differ, do not use the mirror as a substitute for upstream. + +## 7. Gitea Mirror Rules + +If a Gitea repository is a pull mirror: + +- it is a sync target, not a dev target +- pushes may fail or be meaningless +- it should be treated as read-only for development + +Use mirror repos for: + +- backup +- browsing +- clone acceleration +- temporary upstream fallback when verified fresh + +Do not use mirror repos for: + +- long-term feature branch work +- main development push target +- authoritative branch ownership + +## 8. SSH Rules for Gitea + +Use Gitea built-in SSH, not random container SSH assumptions. + +Example working clone form: + +```bash +git clone ssh://git@100.64.0.8:2222/admin/new-api-dev.git +``` + +If SSH suddenly breaks after a server-side SSH mapping change: + +- verify host port mapping +- verify Gitea built-in SSH port +- refresh local `known_hosts` if host key changed + +Example: + +```bash +ssh-keygen -R '[100.64.0.8]:2222' +ssh -T -p 2222 git@100.64.0.8 +``` + +## 9. Required Remote Configuration for This Project + +Current expected shape: + +- `upstream` -> official GitHub repository +- `gitea` -> writable Gitea development repository + +Expected result style: + +```text +gitea ssh://git@100.64.0.8:2222/admin/new-api-dev.git (fetch) +gitea ssh://git@100.64.0.8:2222/admin/new-api-dev.git (push) +upstream https://github.com/QuantumNous/new-api.git (fetch) +upstream https://github.com/QuantumNous/new-api.git (push) +``` + +Expected tracking style: + +- `main` -> `upstream/main` +- `home` -> `gitea/home` + +## 10. Forbidden Operations + +Do not do the following unless you explicitly know why: + +- push local feature work into a pull mirror repo +- remove `upstream` and pretend Gitea mirror is always equal to GitHub +- develop directly on `main` +- rewrite shared branch history without understanding the impact +- force-push `main` +- use mirror repos as the only source of upstream truth +- change remote roles casually + +## 11. Minimal Recovery Rules + +If repository roles become confused: + +1. inspect remotes +2. identify which repo is writable and which is mirrored +3. restore: + - `upstream` -> official source + - `gitea` -> writable dev repo +4. restore tracking: + - `main` -> `upstream/main` + - dev branch -> `gitea/` + +Useful commands: + +```bash +git remote -v +git branch -vv +git config --get branch.main.remote +git config --get branch.main.merge +git config --get remote.pushDefault +``` + +## 12. Recommended Defaults + +Set default push target to writable Gitea: + +```bash +git config remote.pushDefault gitea +``` + +Set `main` tracking to upstream: + +```bash +git branch --set-upstream-to=upstream/main main +``` + +Set dev branch tracking to Gitea: + +```bash +git branch --set-upstream-to=gitea/home home +``` + +## 13. Human Rule + +If you cannot explain, in one sentence, which remote is: + +- official upstream +- writable dev remote +- mirror + +then stop and fix the repository configuration before doing more Git work. diff --git a/ops/remote/README.md b/ops/remote/README.md new file mode 100644 index 00000000..5cfcfdb6 --- /dev/null +++ b/ops/remote/README.md @@ -0,0 +1,9 @@ +# Remote Runtime Notes + +这个目录记录远程主机运行事实,避免把主机级流水账继续堆回根文档。 + +约定: + +- 一台主机一份 `*.AGENT.md` +- 只写运行事实、入口、路径、端口、依赖和排障命令 +- 项目规则仍放在根 `AGENTS.md` / `CLAUDE.md` diff --git a/ops/remote/TEMPLATE.AGENT.md b/ops/remote/TEMPLATE.AGENT.md new file mode 100644 index 00000000..0ce1f1f7 --- /dev/null +++ b/ops/remote/TEMPLATE.AGENT.md @@ -0,0 +1,73 @@ +# Remote Host AGENT Template + +## 1. Host Identity +- Host name: +- Host role: +- Region or environment: +- Primary access path: +- Tailscale IP: +- Other important IPs or domains: + +## 2. Access and Safety +- SSH profile or connection method: +- Primary operator: +- Privilege model: +- Proxy requirements: +- Secrets location: +- Important do-not-touch items: + +## 3. Runtime Topology +- Main deployment styles on this host: +- Shared Docker networks: +- Shared databases or caches: +- Host-level ports in use: +- Reverse proxy or ingress layer: + +## 4. Project Inventory + +### Project: +- Purpose: +- Deploy mode: +- Runtime entrypoint: +- Source repo path: +- Runtime directory: +- Main service or container names: +- Public or internal endpoints: +- Config files: +- Data location: +- Backup location: +- Logs and inspection commands: +- Upgrade path: +- Known traps: + +## 5. Git and Repository Strategy +- Writable repositories: +- Mirror repositories: +- Upstream repositories: +- Default push targets: +- Branch strategy: +- Sync workflow: + +## 6. Data and Backup +- Databases in use: +- Named volumes or bind mounts: +- Backup commands: +- Restore notes: +- High-risk destructive actions to avoid: + +## 7. Routine Operations +- Check health: +- Check logs: +- Restart service: +- Restart containers: +- Verify ports: +- Verify external access: + +## 8. Incident Notes +- Recent incidents: +- Root causes found: +- Permanent fixes applied: +- Remaining risks: + +## 9. Change Log +- YYYY-MM-DD: diff --git a/ops/remote/minione-ubuntu-infra-4c16g120g.AGENT.md b/ops/remote/minione-ubuntu-infra-4c16g120g.AGENT.md new file mode 100644 index 00000000..5c512605 --- /dev/null +++ b/ops/remote/minione-ubuntu-infra-4c16g120g.AGENT.md @@ -0,0 +1,63 @@ +# Remote Host AGENT — minione-ubuntu-infra-4c16g120g + +## Host Identity + +- Host name: `minione-ubuntu-infra` +- Tailscale IP: `100.64.0.8` +- 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:@127.0.0.1:5433/new-api` +- `REDIS_CONN_STRING=redis://:@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.8:3001/` +- SSH: `ssh -p 2222 git@100.64.0.8` +- 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'`