You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4.7 KiB

Windows SSH 一键部署设计

目标

在开发机执行一个 PowerShell 命令完成前端和后端构建、上传、备份、发布、后端重启、Nginx 平滑重载以及基础可用性检查。目标服务器为 Windows使用已验证可连接的 OpenSSH 服务。

范围与约束

  • 开发机工作区:E:\workspace\dianshang
  • 前端工程:e-commerce-internet,使用 npm run build:prod,产物为 dist
  • 后端工程:link_commerce,使用 Maven 构建,目标 JAR 为 link_commerce-2.7.12.jar
  • 服务器通过 SSH 以 Administrator 账号连接;主机地址不得硬编码在可提交的私密配置中以外。
  • 前端发布目录:D:\nginx-1.19.3.1\html\dist
  • 后端发布目录:D:\dianshang-test-http-deploy-20260629-093129
  • Nginx 根目录:D:\nginx-1.19.3.1,发布时必须先执行 nginx -t,成功后才执行 nginx -s reload
  • 后端监听端口:7548
  • 不在部署脚本、Git 跟踪文件、日志或命令行参数中保存数据库密码。

方案

采用「SSH + 服务器启动脚本 + Windows 计划任务」:

  1. 本地部署入口读取未跟踪的 deploy.local.psd1其中只包含服务器地址、用户名、SSH 私钥路径等非代码环境信息。
  2. 入口先验证 sshscp、Node.js 与 Maven 可用,再顺序构建前端和后端;任一构建失败即停止,绝不上传旧产物。
  3. 入口为本次发布生成唯一临时目录,将前端 dist 和 JAR 打成 ZIP 后通过 SCP 上传至服务器临时目录。
  4. 远程发布脚本先解压到同盘临时目录,校验前端入口文件和 JAR 存在后,再分别把当前前端目录与 JAR 复制到带时间戳的备份目录。
  5. 远程脚本仅停止命令行中明确匹配目标 JAR 的 Java 进程,避免误杀其他 Java 程序;随后替换前端目录和 JAR。
  6. 后端由服务器本地 Start-CommerceBackend.ps1 启动。该脚本从仅服务器可读的 backend.private.ps1 加载数据库连接参数,在后台启动 Java并将标准输出和错误输出写入后端目录的 logs。计划任务 CommerceBackend 负责机器启动时运行该启动脚本;发布脚本通过 schtasks /Run 重启它。
  7. 远程脚本等待 7548 端口监听如未就绪则返回错误和日志路径。Nginx 配置语法检查成功后执行平滑重载,并以本机 HTTP 请求确认 Nginx 可响应。
  8. 失败时不删除备份;远程脚本报告备份路径和失败阶段。自动回滚不纳入第一版,以避免在未知的业务启动失败场景下覆盖调查证据;提供一个显式 rollback.ps1 入口作为后续可选操作。

文件边界

  • deploy/deploy.ps1:开发机的一键入口;只负责编译、打包、传输、调用远程脚本与汇总结果。
  • deploy/deploy.local.psd1.example:可提交的配置模板,不含凭据;真实 deploy.local.psd1 被忽略。
  • deploy/server/Initialize-CommerceDeployment.ps1:仅首次执行;创建服务器目录、私密配置模板、启动脚本和计划任务。
  • deploy/server/Publish-Commerce.ps1:每次发布执行;解压、备份、切换文件、重启后端并重载 Nginx。
  • deploy/server/Start-CommerceBackend.ps1:只在服务器上运行;从私密配置读取 Spring 启动参数并启动 JAR。
  • deploy/tests/DeployScript.Tests.ps1Pester 测试,以模拟 SSH/SCP 与临时目录验证入口的命令构造、失败中止和不泄露私密配置。

配置与安全

  • 使用专用 SSH 密钥;私钥保存在开发机用户目录并由 deploy.local.psd1 引用。脚本不读取或记录登录密码。
  • backend.private.ps1 仅存在于服务器后端目录,包含数据源 URL、用户名与密码应只允许 Administrator 读取,且不通过 SCP 回传。
  • 先前在聊天中暴露过的数据源密码需要由管理员尽快轮换,然后将新值仅写入服务器的私密配置。
  • 远程命令的路径均采用固定、已给定的绝对路径,不接受来自发布包的可执行命令。

验证

  • 本地Pester 验证部署脚本在构建失败时不触发 SCP在成功路径下构造正确的远程调用且日志文本不包含私密配置字段。
  • 本地:执行前端构建与 Maven 打包,确认产物存在。
  • 服务器初始化:确认计划任务存在且启动脚本可读取私密配置。
  • 发布:确认新的前端 index.html 与后端 JAR 已到位,7548 监听,且 nginx -t 和 HTTP 检查成功。

非目标

  • 不自动执行数据库 SQL 或结构迁移。
  • 不修改 Nginx 反向代理规则;仅测试并平滑重载现有配置。
  • 不在第一版接入 CI/CD、Git 标签或多服务器滚动发布。