Files
pangolin/CLAUDE.md
T
wangjia 53caaf54f0
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
docs: 同步 EC2 栈删除后的文档
- CLAUDE.md 重写:去掉 EC2/marzban 部署、架构、cutover/rollback 命令、自动部署 CD;
  改为自有 VPS 自建方向(RackNerd Debian 12、ssh racknerd 免密、512MB→SQLite)、
  补 server/ Go 后端与多数据库(DB_DRIVER)说明;保留设计 token 单源段
- 删 docs/回滚手册.md(EC2 edge 切换/回滚,脚本已删)
- 删 docs/备份与灾备.md(EC2 MySQL/marzban xtrabackup→S3,backup 栈已删)
- app/kernel/poc/README.md:REALITY 参数来源由 EC2 改为自建节点(single-node)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 07:01:13 +08:00

85 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 这个仓库是什么
Pangolin 是面向中国大陆用户的终端 VPN(科学上网)项目,**自研全栈**:
- `server/` —— Go 控制面 + 节点 agent + sing-box 数据面(HTTP API + gRPC mTLS)
- `client/` —— Flutter 客户端(内嵌 sing-box + TUN 全局代理)
- `web/` —— 用户中心(usercenter)+ 官网(website)
- `deploy/` —— 节点部署:`bootstrap/`(新机初始化)+ `single-node/`(整套自建栈)
- `design/` —— 设计 token 单源 + 规格;`docs/` / `plan/` —— 文档与计划
> 历史:早期借 EC2 上的 Marzban 临时顶现网。**本仓库已不再管理那套 EC2/marzban 部署**
> (相关 `deploy/edge|singbox|scripts|docker-compose.yml` 与 Gitea 自动部署 CD 已删除),
> 全面转向在自有 VPS 上跑自研栈。
## 部署目标:自有 VPS 节点
当前节点:**RackNerd VPS `107.172.55.251`**(Debian 12 bookworm,root,1 核 / 512MB / 2G swap)。
- **SSH 免密**:本机 `~/.ssh/config` 有别名 `racknerd`(密钥登录,密码登录已禁)→ 直接 `ssh racknerd`
- 已用 `deploy/bootstrap/init.sh` 加固(ufw + fail2ban + BBR + swap + pangolin 用户)。
- **512MB 内存是硬约束**:控制面用 **SQLite**(见下),不要在这上面跑 MySQL 8。
- 改任何机器系统(装包/改配置/重装)前**先问用户**(只读操作除外)。
## deploy/ 结构
```bash
# ① 新机初始化(幂等,root 跑一次;后续每台新机复用)
# 远程:scp -r deploy/bootstrap racknerd:/root/ && ssh racknerd 'cd /root/bootstrap && bash init.sh'
deploy/bootstrap/init.sh # 加固/swap/BBR/pangolin用户/ufw/fail2ban/Telegram监控
deploy/bootstrap/monitor/ # pangolin-monitor(节点自报)+ deadman-watch(常在线主机探活)
# ② 整套自建栈(一台 VPS 跑 MySQL/Redis + 控制面 + agent + sing-box,端到端真连)
sudo VPS_IP=<公网IP> bash deploy/single-node/deploy.sh
```
`deploy/bootstrap/bootstrap.env``/etc/pangolin-monitor.env``deploy/single-node`
`/etc/pangolin*` 密钥均 **不入 git**
## server/ 后端(Go)
- 二进制:`cmd/{server,agent,nodectl,migrate}`;`go build ./...` 直接编译,免确认。
- 控制面 HTTP API(`:8080`)+ gRPC agent 服务(`:9443`, mTLS);agent 自 enroll → 渲染
sing-box 配置 → `systemctl restart sing-box`。客户端连节点真实出网。
### 数据层:多数据库(一个环境变量切换)
server 已与具体 DB 解绑(裸 SQL + 薄方言层,`internal/db/dialect.go`):
- `DB_DRIVER=mysql`(默认)| `sqlite`;`DB_DSN`(mysql DSN / sqlite 文件路径或 `:memory:`)。
- 迁移分 `server/migrations/{mysql,sqlite}/` 两套,`migrate` 按驱动选源(`golang-migrate`)。
- SQLite 用 `modernc.org/sqlite`(纯 Go 免 CGO)+ `_txlock=immediate`(等价 MySQL 行锁的悲观语义)。
- 测试:`go test ./...`(含 SQLite 实库测试,免 docker)+ `./server/run_sqlite_test.sh`;
MySQL 集成测试 `./server/run_mysql_test.sh`(需 docker)。
- **改 schema/查询**:upsert 用 `dialect.Upsert(...)`(中性 `EXCLUDED.col` 记法),行锁用
`dialect.LockForUpdate()`;时间等一律 Go 端算好传 `?`,**不要**用 `UTC_TIMESTAMP()`/
`NOW()`/`FIELD()` 等 MySQL 专属构造(已全部清除,加回会破坏可移植性)。
## CI/CD
`.gitea/workflows/ci.yml`(runner label `nas`):shellcheck(bootstrap/single-node 脚本)、
OpenAPI 结构校验、UI 文案脱敏扫描、Flutter analyze+test。**仅校验,无部署动作。**
- 节点部署是手动/按需的(scp+ssh 跑 bootstrap / single-node),不走 CI 自动推送。
## 设计 Token 单源模型
`design/colors_and_type.css` 是**唯一 token 真相源**。改颜色/间距/圆角只改这一个文件,然后:
```bash
# Flutter token(生成 client/lib/pangolin_tokens.gen.dart
node design/codegen/gen_flutter_tokens.mjs
# usercenter / website CSS token(由 prebuild/predev 钩子自动触发,也可手动)
cd web/usercenter && npm run gen:tokens
cd web/website && npm run gen:tokens
```
- `client/lib/pangolin_tokens.gen.dart`**勿手改**,由生成器覆盖。
- `client/lib/pangolin_theme.dart` — 只含实现层(`PangolinScheme`/`PangolinText`/`PangolinTheme`),不含 token 数值。
- `design/flutter/` 已删除;Flutter 组件 canonical 实现在 `client/lib/widgets/`,规格在 `design/preview/`
- **禁止**再向 `design/` 提交 Dart/TS 组件代码副本(会漂移)。