# 前端独立构建与测试服发布 在前端 `game-busAdminSystem` 仓库的 `kra` 分支根目录执行。全部命令只需要前端源码,不需要 Go 仓库或后端配置。 本机需要 Node.js 22.12 及以上、pnpm 10 及以上、Git。生成发布包还需 `tar`;发布需 OpenSSH 的 `ssh` / `scp`。Windows、macOS、Linux 使用相同的 pnpm 命令。Docker 源码构建另需本机 Docker;发布包方式在服务器构建镜像,本机不需要 Docker。 ## 1. 只构建静态文件 ```sh pnpm install --frozen-lockfile pnpm build ``` 产物是 `dist/`。生产接口使用同域 `/api`,前端包里不写数据库密码、SDK 密钥或 SSH 密码。 ## 2. 独立打包 先提交前端改动;脚本会检查前端目录的已修改、暂存及未跟踪文件,构建过程中生成的 `src/pathInfo.json` 也须与提交一致。 ```sh pnpm package:test # 自定义版本;默认版本为当前提交号前 12 位 pnpm package:test --tag web-20261105-01 ``` 脚本安装锁定依赖、执行生产构建,生成: ```text .cache/deploy/sw2-frontend-<版本>.tar.gz .cache/deploy/sw2-frontend-<版本>.tar.gz.sha256 ``` 包内只有 `dist/`、运行镜像的 `Dockerfile`、`nginx.conf`、服务端 `deploy.sh` 与 `release.json`。版本清单记录提交号、源码树和构建时间,静态目录中的 `build-info.json` / `version.txt` 用于发布核对。已有同名包不会被覆盖;发布时复用该包或指定新版本。 `--skip-install` 可在已经按锁文件安装依赖后使用;`--output <目录>` 可指定包输出目录。在 `sw-new/web` 中开发时也可运行:检查只覆盖前端,后端本地配置不影响打包。若已在本地生成分仓提交,可传 `--source-ref codex/publish-web`,脚本会验证该提交的根目录与当前前端源码树一致。 ## 3. 构建并推送 Harbor 镜像 ```sh pnpm build:docker pnpm build:docker --tag web-20261105-01 # 构建后推送到 Harbor docker login harbor.fuhua91.com pnpm push:docker --tag web-20261105-01 ``` 镜像仓库统一为 **`harbor.fuhua91.com/game/sw2:<版本>`**,默认版本仍为源码提交号前 12 位。`build:docker` 只构建,`push:docker` 构建并推送到 Harbor 的 `game/sw2` 仓库。使用已有 Docker 登录凭据或机器人账号,本机推送账号需要 `game/sw2` 的 push 权限,服务器拉取账号需要 pull 权限;密码不写入脚本或发布包。 `deploy/Dockerfile` 在 Node 容器内完成源码构建,`deploy/runtime.Dockerfile` 用于发布包的服务器构建。根目录 `Dockerfile` 与 Windows `pnpm pack:docker <版本>` 入口也使用上述 Harbor 仓库;`pack:docker` 构建并推送,传 `-SaveArchive` 可额外导出离线镜像到忽略的 `.cache/docker/`。 本机构建检测到 Buildx 时,输出 Linux amd64 的单平台 Docker 镜像并关闭默认证明附件,兼容测试服 Docker 18.06;没有 Buildx 时使用传统构建器。 ## 4. 发布到 sw2 测试服 默认连接 `root@192.168.2.226:22`,部署根目录 `/www/wwwroot/sw2.fuhua91.com`。使用本机 SSH 密钥或 SSH agent;首次使用先用 `ssh root@192.168.2.226` 确认主机指纹和登录权限。脚本使用非交互 SSH,仓库不保存密码。 ```sh # 本机打包,服务器构建并推送 Harbor,再拉取部署 pnpm deploy:test # 已通过 push:docker 推送:测试服直接从 Harbor 拉取,不再上传包或重新构建 pnpm deploy:test --image-tag web-20261105-01 # 复用已经生成的包 pnpm deploy:test --archive .cache/deploy/sw2-frontend-web-20261105-01.tar.gz # 构建、推送、拉取并预检,保持当前容器运行 pnpm deploy:test --archive .cache/deploy/sw2-frontend-web-20261105-01.tar.gz --build-only # 也可仅预检 Harbor 中的现有镜像 pnpm deploy:test --image-tag web-20261105-01 --build-only # 使用其他 SSH 账号、端口或密钥 pnpm deploy:test --archive <发布包.tar.gz> --user deploy --port 22 --identity <私钥路径> ``` 可用 `--host` 与 `--directory` 覆盖测试服务器和部署根目录。服务器账号需要该目录写权限及 Docker 权限,并已执行 `docker login harbor.fuhua91.com`。发布包模式在服务器执行 push,需 push/pull 权限;`--image-tag` 模式只需 pull 权限。现有的 `sw2-net` 网络、`sw2-backend:8000` 服务与宝塔反向代理应已就绪;服务端脚本兼容 Docker 18.06,不依赖 Docker Compose。 若服务器已有其他项目的 Docker 登录,可为本项目前端单独配置。脚本优先读取部署根目录 `harbor-docker/config.json`,不存在时使用当前账号默认 Docker 配置: ```sh install -d -m 700 /www/wwwroot/sw2.fuhua91.com/harbor-docker docker --config /www/wwwroot/sw2.fuhua91.com/harbor-docker login harbor.fuhua91.com chmod 600 /www/wwwroot/sw2.fuhua91.com/harbor-docker/config.json ``` 发布过程: 1. 验证包结构和版本,上传至 `frontend-releases/`,校验 SHA-256。相同版本只接受同一个发布包。 2. 发布包模式先构建并推送 `harbor.fuhua91.com/game/sw2:<版本>`;两种模式随后都从 Harbor 拉取,取得镜像摘要,按 `harbor.fuhua91.com/game/sw2@sha256:…` 运行临时容器并检查 `/healthz`、`/version.txt` 和 `/api/health`。镜像推送或拉取失败时,当前容器继续运行。 3. 预检通过后,只替换 `sw2-frontend`,仍绑定 `127.0.0.1:9601`。上一版保留为停止状态的 `sw2-frontend-previous`。 4. 正式容器使用同一个已验证的镜像摘要;再次检查失败时自动恢复上一版。成功后写入 `current-frontend-release`,镜像摘要保存在 `frontend-images/<版本>.ref`。后端容器、数据库、后端配置及联合发布的 `current-release` 均不修改。 Nginx 使用 Docker DNS 动态解析后端地址,后端独立重建后无需重建前端镜像。对外仍访问 `http://sw2.fuhua91.com`。 ## 回退与验证 指定 Harbor 中保留的旧版本即可回退,仍只操作前端: ```sh pnpm deploy:test --image-tag <旧版本> ``` 服务端手工执行同样的脚本: ```sh bash /www/wwwroot/sw2.fuhua91.com/frontend-releases/<版本>/deploy.sh <版本> curl -fsS http://127.0.0.1:9601/version.txt curl -fsS http://127.0.0.1:9601/api/health docker inspect --format '{{.Config.Image}}' sw2-frontend ``` 发布脚本通过文件锁阻止并发前端发布。永久回归测试覆盖包路径与版本验证、Harbor 推送/拉取失败、缺失镜像摘要、直接拉取模式、预检失败及发布后回退,以及后端容器保持不变: ```sh pnpm test:release ``` 测试需要 Bash;Windows 可使用 Git for Windows 自带的 Bash,或通过 `BASH` 环境变量指定。