53caaf54f0
- 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>
85 lines
4.4 KiB
Markdown
85 lines
4.4 KiB
Markdown
# 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 组件代码副本(会漂移)。
|