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

4.4 KiB
Raw Blame History

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/ 结构

# ① 新机初始化(幂等,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.envdeploy/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 真相源。改颜色/间距/圆角只改这一个文件,然后:

# 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 组件代码副本(会漂移)。