Files
YANG JIANKUAN 43a753963c 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>
2026-09-03 17:38:38 +08:00

58 lines
4.5 KiB
Markdown
Raw Permalink 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.

---
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 代理环境变量sshpnpmcurl 都直连。
## 结果怎么读
- 最后一行 `部署完成:<目标> @ <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` 与环境变量指向它。