feat: 新增 deploy Skill 与 LA 生产部署文档
线上为 1 核 1.9G 机器,放弃 Docker:Node 直跑 + systemd 守护, 前端本地构建后由服务端静态托管,HTTPS 与反代由 aaPanel 的 nginx 管理。 部署脚本支持 web/server/all 三种目标,含本地类型检查与单测、 暂存目录原子换入、健康检查失败自动回滚源码、本地与远端源码树指纹比对 及公网校验。首次部署与一次性配置写在 docs/DEPLOY.md。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
57
.claude/skills/deploy/SKILL.md
Normal file
57
.claude/skills/deploy/SKILL.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
name: deploy
|
||||
description: 把 proxy-station 部署到 LA 生产服务器(ps.la.njcqtechaicoding.com)。可以只部署前端、只部署后端,或前后端一起。凡是用户提到「部署」「发布」「上线」「推到服务器」「更新线上」「让线上生效」「同步到 la」,或改完代码想在生产环境看效果,都用这个 Skill,即使没有明说「部署」二字。
|
||||
---
|
||||
|
||||
# 部署 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 只负责日常的代码更新。
|
||||
|
||||
## 用法
|
||||
|
||||
```bash
|
||||
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 与单测。线上没有测试环境,这是最后一道拦截。
|
||||
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>` 才算成功。把这一行连同校验段落转述给用户。
|
||||
- 输出里出现 `(工作区有未提交改动)` 时要提醒用户:线上跑的是未提交的代码,之后应当提交或有意识地保持。
|
||||
- `前端产物指纹不一致` 几乎只有一种原因:推送中断。重跑一次 `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` 与环境变量指向它。
|
||||
Reference in New Issue
Block a user