diff --git a/AGENTS.md b/AGENTS.md index ca6b887b..2f5a792b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -138,7 +138,16 @@ For request structs that are parsed from client JSON and then re-marshaled to up ### 1. 部署与配置位置 - 远程服务器:`个人-minione-ubuntu-infra-4c16g120g` -- `new-api` 以 Docker 容器运行,容器名:`new-api` +- `new-api` 当前由宿主机 `systemd` 直接运行,不再以应用 Docker 容器运行。 +- 当前部署目录: + - `/root/new-api-deploy` +- 当前关键文件: + - systemd 单元:`/etc/systemd/system/new-api.service` + - 运行环境:`/root/new-api-deploy/.env.runtime` + - 可执行文件:`/root/new-api-deploy/new-api` +- 当前共享基础设施入口: + - PostgreSQL:`127.0.0.1:5433` + - Redis:`127.0.0.1:6379` - 渠道配置不在 `docker-compose.yml` 里维护,核心数据在 PostgreSQL 数据库表中: - `channels` - `abilities` @@ -199,7 +208,7 @@ For request structs that are parsed from client JSON and then re-marshaled to up - 查问题时必须先看数据库 `options` 实际内容。 ### 7. 线上热同步行为 -- `new-api` 会定时从数据库同步 `options` 和 `channels`,不需要每次都重启容器。 +- `new-api` 会定时从数据库同步 `options` 和 `channels`,不需要每次都重启服务。 - 日志关键字: - `syncing options from database` - `syncing channels from database` @@ -224,170 +233,50 @@ For request structs that are parsed from client JSON and then re-marshaled to up - 是上游不通 - 还是服务端计费配置缺失 -## 9. 当前线上部署形态(2026-04-04 更新) -- 远程服务器仍是:`个人-minione-ubuntu-infra-4c16g120g` -- `new-api` **不再**以 Docker 应用容器运行;当前由宿主机 `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` -- 关键文件: - - 二进制:`/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` - - systemd 单元文件:`/etc/systemd/system/new-api.service` +## 9. 远程运行事实入口 +- `AGENTS.md` 只保留项目规则、代码约束和少量排障结论。 +- 具体远程部署、主机拓扑、端口、备份、Gitea 运行方式、镜像策略、方案 A Git 工作流,统一收口到: + - `ops/remote/README.md` + - `ops/remote/TEMPLATE.AGENT.md` + - `ops/remote/minione-ubuntu-infra-4c16g120g.AGENT.md` +- 后续如果远程运行事实再变,不要继续把细节堆回这里,直接更新 `ops/remote/` 下对应主机文档。 -## 10. 依赖服务与连接方式(2026-04-04 更新) -- PostgreSQL 和 Redis 仍然跑在 Docker 中,但**只作为依赖容器**存在,不再承载应用本体。 -- 当前容器: - - PostgreSQL:`postgres` - - Redis:`redis` -- 当前宿主机固定入口: - - 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 容器时不需要改应用配置。 +## 10. 当前远程管理约定 +- 当前 `infra` 主机的真实运行状态以 `ops/remote/minione-ubuntu-infra-4c16g120g.AGENT.md` 为准。 +- 这份主机文档已经覆盖: + - `new-api` 的 systemd 源码部署 + - `new-api` 的远程源码构建链(Go + Bun) + - `new-api-upgrade` 升级脚本 + - Gitea 的 Docker Compose 部署 + - PostgreSQL / Redis 的共享方式 + - Gitea 访问 GitHub 的代理要求 + - `admin/new-api` 镜像仓库 + - `admin/new-api-dev` 可写开发仓库 + - 本地仓库的方案 A 同步流程 +- 新机器、新环境、新项目都按同样模式在 `ops/remote/` 下新增实例文档,不要再往项目根 `AGENTS.md` 追加主机级流水账。 -## 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` - -## 12. 运维入口与排障顺序(2026-04-04 更新) -- 现在排障先看 `systemd`,不是先看 Docker 应用容器: +## 11. 当前远程启动与升级约定(2026-04-12 更新) +- `new-api` 启动命令由 `systemd` 执行: + - `ExecStart=/root/new-api-deploy/new-api --port 3000 --log-dir /root/new-api-deploy/logs` +- 正常启动/重启入口: + - `systemctl restart new-api` - `systemctl status new-api` - `journalctl -u new-api -n 200 --no-pager` - - `journalctl -u new-api -f` -- 服务健康检查: - - `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` - -## 13. 后续升级原则(2026-04-04 更新) -- 升级时优先选择新的**稳定 tag**,不要直接拿 `main` 或 `latest` 当生产版本。 -- 合理流程应该是: - 1. 为目标稳定 tag 建单独部署目录或 worktree - 2. 编译产出新二进制 - 3. 保留 PG volume,不迁移数据库文件路径 - 4. 让 systemd 指向新版本 - 5. 验证 `api/status`、日志、数据库连接再收尾 -- 如果有人再次看到 `docker-compose.yml` 里定义了 `new-api` 服务,不要想当然地认定线上还在用容器跑应用;先查: - - `systemctl status new-api` - - `ss -lntp | grep :3000` - -## 14. infra 虚拟机上的 Gitea 部署(2026-04-04 更新) -- 远程服务器:`个人-minione-ubuntu-infra-4c16g120g` -- Gitea 当前以 Docker 方式部署,不与 `new-api` 共用应用容器。 -- 当前镜像固定为稳定版本: - - `docker.gitea.com/gitea:1.25.5` -- 容器名: - - `gitea` -- 访问端口: - - Web:`3001` - - SSH:`2222` -- 当前 Web 根地址配置为: - - `http://100.64.0.11:3001/` -- 如果后续公网域名或访问地址变了,优先修改: - - `/opt/gitea/data/gitea/conf/app.ini` - - 重点字段:`DOMAIN`、`SSH_DOMAIN`、`ROOT_URL` - -## 15. Gitea 数据与配置位置(2026-04-04 更新) -- Gitea 部署目录: - - `/opt/gitea` -- compose 文件: - - `/opt/gitea/docker-compose.yml` -- Gitea 数据目录(bind mount,不是 named volume): - - `/opt/gitea/data` -- 主配置文件: - - `/opt/gitea/data/gitea/conf/app.ini` -- 敏感环境变量文件(root only): - - `/opt/gitea/.env` -- 这份 `.env` 里包含: - - PostgreSQL 密码 - - Gitea 管理员初始密码 - - Gitea 各类 secret/jwt token -- 不要把 `/opt/gitea/.env` 提交到仓库、复制到公开位置或随手改权限。 - -## 16. Gitea 与 PostgreSQL 的关系(2026-04-04 更新) -- Gitea **复用了现有 PostgreSQL 实例**,但没有复用 `new-api` 的数据库。 -- Gitea 专用 PostgreSQL 角色与数据库: - - role:`gitea` - - database:`gitea` -- 连接方式不是宿主机 `127.0.0.1:5433`,而是容器内直接走共享 Docker 网络: - - host:`postgres:5432` -- 共享网络: - - `new-api_new-api-network` -- 原则: - - 复用的是 PG 实例,不是 `new-api` 数据库。 - - 不要把 Gitea 表写进 `new-api` 库,那是纯粹找死。 - -## 17. Gitea 运维与排障(2026-04-04 更新) -- 查看状态: - - `cd /opt/gitea && docker compose ps` - - `docker ps | grep gitea` -- 查看日志: - - `docker logs -f gitea` -- 重启: - - `cd /opt/gitea && docker compose restart` -- 健康检查: - - `curl --noproxy '*' http://127.0.0.1:3001/` -- 由于远程机器设置了代理环境变量,使用本机 `curl` 打本机端口时优先加: - - `--noproxy '*'` -- 否则很容易出现假的 `502`,把问题看错。 -- Gitea SSH 应走**内置 SSH 服务**,当前正确的宿主机端口映射是: - - `2222:2222` -- 不要把宿主机 `2222` 映射到容器 `22`。 - - 那样连到的是容器里的 OpenSSH,不是 Gitea SSH,用户公钥会“看起来加了但就是登不上”。 - -## 18. Gitea 初始化状态(2026-04-04 更新) -- 当前已完成初始化,不是安装向导状态。 -- 首页应能看到: - - `Explore` - - `Sign In` -- 当前已创建管理员账号: - - 用户名:`admin` -- 初始密码不写进文档正文,去看: - - `/opt/gitea/.env` -- 第一次登录后应尽快修改管理员密码。 -- 当前推荐通过 Tailscale 地址访问: - - Web:`http://100.64.0.11:3001/` - - SSH:`ssh -p 2222 git@100.64.0.11` -- 当前设备的 SSH 公钥已加入 `admin` 账号,key title 为: - - `qingse-macbook-id_ed25519` -- 如果后续再次修改了 `2222` 的目标服务,客户端可能需要刷新: - - `~/.ssh/known_hosts` - -## 19. Gitea 上的 new-api 镜像仓库(2026-04-04 更新) -- 已在 Gitea 中创建仓库: - - `admin/new-api` -- 当前不是普通仓库,而是 **GitHub pull mirror**: - - 上游:`https://github.com/QuantumNous/new-api.git` - - Gitea 地址:`http://100.64.0.11:3001/admin/new-api` - - SSH clone:`ssh://git@100.64.0.11:2222/admin/new-api.git` -- 当前镜像同步间隔: - - `24h0m0s` -- 这类 mirror 的核心用途是同步 Git 数据: - - branches - - tags - - commits -- 不要把它误解成 GitHub 全量镜像站。 - - 现在配置的不是 GitHub issue / PR / release 的持续双向同步。 - - 它的重点是把仓库代码历史持续拉到 Gitea。 +- 远程源码升级入口: + - `/usr/local/bin/new-api-upgrade` +- 这个脚本当前会执行: + 1. `git fetch origin` + 2. 切到 `home` + 3. `git reset --hard origin/home` + 4. `bun install` + 5. `bun run build` + 6. `go build` + 7. `systemctl restart new-api` + 8. 健康检查 `http://127.0.0.1:3000/api/status` +- 远程主机已补装源码构建工具链: + - `go` + - `bun` +- 关键注意事项: + - `new-api` 的前端产物 `web/dist` 是构建必需品,不能只跑 `go build` + - 当前仓库里的 `VERSION` 文件可能为空;升级脚本会回退到 Git 提交号作为版本字符串 + - 远程部署 checkout 是 `/root/new-api-deploy`,不是旧的 `/root/new-api-v0.11.9` diff --git a/ops/remote/GIT_GITEA.AGENT.md b/ops/remote/GIT_GITEA.AGENT.md new file mode 100644 index 00000000..eb1325ce --- /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.11: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.11: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.11: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.11]:2222' +ssh -T -p 2222 git@100.64.0.11 +``` + +## 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.11:2222/admin/new-api-dev.git (fetch) +gitea ssh://git@100.64.0.11: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..c53ba352 --- /dev/null +++ b/ops/remote/README.md @@ -0,0 +1,42 @@ +# Remote Deployment Inventory + +This directory stores AGENT-style operational documents for remote hosts and deployed projects. + +## Purpose + +Use this directory to keep host-level deployment facts in one place so they do not get lost across shell history, chat logs, or ad hoc notes. + +Keep these documents focused on runtime reality: +- where a service actually runs +- which port is really exposed +- where the real data lives +- which repo is writable versus mirrored +- how to inspect, restart, back up, and upgrade + +## File Layout + +- `TEMPLATE.AGENT.md` — reusable template for a new remote host or VM +- `.AGENT.md` — filled document for a specific host + +## Naming Convention + +Use the stable host name in the file name when possible. + +Examples: +- `minione-ubuntu-infra-4c16g120g.AGENT.md` +- `prod-k8s-edge-01.AGENT.md` +- `staging-gpu-node-02.AGENT.md` + +## Suggested Update Rules + +Update the host document whenever one of these changes: +- deployment mode changes, for example Docker to systemd +- runtime ports or hostnames change +- a new database, cache, or volume is introduced +- Git remotes or mirror strategy changes +- backup location or restore procedure changes +- a real incident reveals a hidden dependency or operational trap + +## Current Hosts + +- `minione-ubuntu-infra-4c16g120g.AGENT.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..82b3b771 --- /dev/null +++ b/ops/remote/minione-ubuntu-infra-4c16g120g.AGENT.md @@ -0,0 +1,112 @@ +# Remote Host AGENT — minione-ubuntu-infra-4c16g120g + +## 1. Host Identity +- Host name: `minione-ubuntu-infra` +- Host role: personal infra VM for `new-api` and `gitea` +- Primary access path: Tabby SSH profile `个人-minione-ubuntu-infra-4c16g120g` +- Tailscale IP: `100.64.0.11` +- LAN IP: `192.168.1.3` + +## 2. Runtime Topology +- `new-api` runs as a host `systemd` process +- `gitea` runs in Docker Compose under `/opt/gitea` +- PostgreSQL, Redis, Nginx run as shared Docker infrastructure +- Shared Docker network: `infra-shared` + +## 3. Shared Infrastructure + +### PostgreSQL +- Container: `infra-postgres` +- Host port: `127.0.0.1:5433` +- Docker alias: `infra-postgres:5432` +- Data path: `/srv/infra/postgres/data` +- Backup path: `/srv/infra/postgres/backup` +- Databases: + - `new-api` + - `gitea` + +### Redis +- Container: `infra-redis` +- Host port: `127.0.0.1:6379` +- Docker alias: `infra-redis:6379` +- Data path: `/srv/infra/redis/data` + +### Nginx +- Container: `infra-nginx` +- Host ports: + - `80` + - `443` + +## 4. new-api +- Service name: `new-api` +- Deploy path: `/root/new-api-deploy` +- Runtime env: `/root/new-api-deploy/.env.runtime` +- Binary path: `/root/new-api-deploy/new-api` +- systemd unit: `/etc/systemd/system/new-api.service` +- Health check: + - `curl --noproxy '*' http://127.0.0.1:3000/api/status` + +### Runtime Profile +- `SQL_DSN=postgresql://root:@127.0.0.1:5433/new-api` +- `REDIS_CONN_STRING=redis://:@127.0.0.1:6379/0` + +### Source Build Toolchain +- `go version` -> currently `go1.25.1` +- `bun --version` -> currently `1.3.12` +- `node` / `npm` also exist, but frontend preferred tool is `bun` + +### Source Upgrade Command +- `/usr/local/bin/new-api-upgrade` + +This script currently does: +1. `git fetch origin` +2. `git switch home` +3. `git reset --hard origin/home` +4. `bun install` +5. `bun run build` +6. `go build` +7. `systemctl restart new-api` +8. health check against `127.0.0.1:3000` + +### Important Notes +- `web/dist` is required for a valid backend build because `main.go` embeds it +- `VERSION` may be empty in the current branch; the upgrade script falls back to Git commit hash +- deployment checkout is branch-based now; do not go back to the old detached worktree deployment unless you explicitly mean to + +## 5. 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` +- Data path: `/opt/gitea/data` + +## 6. Git and Repository Strategy +- Writable repo: + - `admin/new-api-dev` +- Mirror repo: + - `admin/new-api` +- Remote deploy checkout: + - `/root/new-api-deploy` +- Deploy branch: + - `home` + +## 7. Routine Operations +- Check app health: + - `systemctl is-active new-api` + - `journalctl -u new-api -n 200 --no-pager` + - `curl --noproxy '*' http://127.0.0.1:3000/api/status` +- Run source upgrade: + - `/usr/local/bin/new-api-upgrade` +- Check infra: + - `docker ps --format '{{.Names}} | {{.Image}} | {{.Ports}}'` + - `ss -lntp | egrep ':3000|:3001|:2222|:5433|:6379|:80|:443'` +- Check gitea: + - `cd /opt/gitea && docker compose ps` + - `docker logs --tail 200 gitea` + - `curl --noproxy '*' http://127.0.0.1:3001/` + +## 8. Current Reality Traps +- Do not treat `new-api/docker-compose.yml` as production truth; production app runtime is `systemd` +- Do not assume PostgreSQL belongs only to `new-api`; `gitea` shares the same PostgreSQL instance +- Do not assume remote host has no source-build capability anymore; Go and Bun are now installed