Files
proxy-station/.claude/skills/deploy/SKILL.md
YANG JIANKUAN 5326c572a2 feat: 合并边缘节点运维并完善 Surge 配置安全
迁入通用节点部署工具、离线交付页生成器和共用技能,隔离真实配置与交付产物。统一 Codex 与 Claude Code 开发约定,补充节点迁移与运维文档。

完善 FINAL、策略组引用、输入校验、Surge 字段编码与 AI DNS 例外保护,增加隔离测试和订阅验证工具。

验证:全量类型检查、44 项单测、前端构建、脚本语法、技能入口与凭据隔离检查均通过。
2026-10-03 23:19:59 +08:00

5.3 KiB
Raw Blame History

name, description
name description
deploy 将 proxy-station 前端、后端或两者部署到 LA 生产服务器。用于用户要求部署、发布、上线、更新线上或同步到 la;生产数据维护使用 update-db。

部署 proxy-station 到 LA

线上是一台 1 核 1.9G 的机器,没有 Docker:后端用 Node 22 直跑、systemd 守护(服务名 proxy-station,代码在 /opt/proxy-station),前端在本机构建后由后端静态托管,HTTPS 与反代由 aaPanel 的 nginx 负责。首次部署与一次性配置(systemd 单元、/etc/proxy-station/env、nginx 站点、证书、数据库迁移)见 docs/DEPLOY.md,本 Skill 只负责日常的代码更新。

本技能由 Codex 与 Claude Code 共用,命令在仓库根目录运行;.agents/skills/deploy 链接到本目录。阅读或加载技能不代表用户授权上线;用户已明确要求本次部署时直接按授权执行,不重复确认。

用法

bash .claude/skills/deploy/scripts/deploy.sh all       # 前后端一起(默认)
bash .claude/skills/deploy/scripts/deploy.sh web       # 只换前端产物,不重启服务
bash .claude/skills/deploy/scripts/deploy.sh server    # 只推后端源码,装依赖并重启服务

可选开关:

开关 作用 什么时候用
--skip-checks 跳过本地 typecheck 与单测 本轮已经跑过且代码没再改
--skip-build 不重新构建前端,直接推现有 web/dist 刚构建过,只是重推
--host <别名> 换目标机器(默认 la) 以后有第二台时

也可用环境变量覆盖 DEPLOY_REMOTE_DIR、DEPLOY_SERVICE、DEPLOY_PUBLIC_URL、DEPLOY_RUN_USER。

怎么选目标

  • 改动只在 web/ 下(页面、样式、前端逻辑)→ web。前端产物是静态文件,后端按请求读盘,换完立刻生效,不打断已连接的客户端拉订阅。
  • 改动在 server/ 或 shared/ → server。shared/ 是前后端共用源码,动了它通常前端也要重建,这时用 all 更稳。
  • 拿不准就用 all,多花的只是一次前端构建的几秒钟。

脚本做了什么,以及为什么

  1. 预检:拒绝大写 ssh 别名(大写会被当作域名走 fake-IP 解析,连不上);确认远端目录与 systemd 单元存在,否则提示先做首次部署。
  2. 本地检查:后端目标先跑 typecheck 与单测。线上没有测试环境,这是最后一道拦截。 节点/组/规则/DNS/生成器变更另按 Surge 变更验证 验证候选订阅,使用本机官方 surge-cli,涉及规则集时通过 scripts/check-surge.py --fetch-rulesets 下载快照验证。单测中本地 Surge CLI 用例在未安装时会跳过,不能据此声称已通过官方校验。
  3. 推送:用 tar 管道走 ssh,不依赖远端 rsync。先解到暂存目录再整体换入,旧版本保留为 *.old,中途失败不会留下半新半旧的目录。
  4. 后端:pnpm install --frozen-lockfile --prod 只装 server 及其 workspace 依赖,然后重启服务,等 /api/health 最多 20 秒。不通过就打印日志、把源码换回 .old 并重启,让线上先恢复。
  5. 校验:不用「命令没报错」当成功。前端比对本地与远端 web/dist 的文件树指纹,并检查公网首页是否已引用新的入口脚本;后端比对 server/src 与 shared/src 的指纹并确认服务 active;最后从本机访问公网健康检查,并确认管理接口不带 token 时返回 401。任何一项不过,脚本以失败退出。

脚本运行时会主动剥掉会话注入的 HTTP 代理环境变量,ssh/pnpm/curl 都直连。

结果怎么读

  • 最后一行 部署完成:<目标> @ <git rev> 才算成功。把这一行连同校验段落转述给用户。
  • 输出里出现 (工作区有未提交改动) 时要提醒用户:线上跑的是未提交的代码,之后应当提交或有意识地保持。
  • 生成器或 shared 变更部署后,从实际 HTTPS 入口取订阅,用 python3 scripts/check-surge.py <私有临时文件> --fetch-rulesets 再验收;健康检查和源码指纹不能证明规则行为正确。受影响的 Clash 用独立目录下的 mihomo -t 验证。
  • 前端产物指纹不一致 几乎只有一种原因:推送中断。重跑一次 web 即可。
  • 公网首页未引用 <入口脚本> 而指纹一致:浏览器或中间缓存,稍等再试;aaPanel 的反代模板对 js 只缓存 1 分钟。
  • pnpm install 失败:多半是本地 package.json 改了但锁文件没更新。本地 pnpm install 后连锁文件一起提交,再部署。
  • 健康检查失败并回滚:回滚只恢复源码,不恢复依赖。到本地用 pnpm --filter @proxy-station/server start 复现,别在线上反复重启。

边界

  • 数据库迁移、ADMIN_TOKEN、nginx 与证书属于另行授权的首次配置或维护任务,见 docs/DEPLOY.md;本次代码部署授权不包含这些操作。已有明确授权时不重复确认。
  • 不做 git 提交。部署与提交是两件事,用户没要求就不要顺手提交。
  • 如果用户要部署到 LA 之外的机器,先确认那台机器已按 docs/DEPLOY.md 完成首次部署,再用 --host 与环境变量指向它。