GitHub Actions 零基建自动化部署:SSH 免密三道安全门与 PM2 弹性管控

发布时间:2026/7/21 5:30:32

GitHub Actions 零基建自动化部署:SSH 免密三道安全门与 PM2 弹性管控 导读每次发布都要经历“本地推代码 → SSH登录服务器 → git pull → 重启服务”的繁琐流程通过 GitHub Actions你可以让这整个流程完全自动化真正实现“代码推送即上线”。本文将以 Node.js 项目为例带你从零配置一套安全、零停机的自动化部署流水线。 为什么需要 CI/CD 自动化部署引入 CI/CD持续集成与持续部署的核心收益在于节省时间每次部署节省 5~15 分钟手动操作。减少失误人工操作容易遗漏步骤自动化流程每次完全一致。快速回滚出现问题时可快速恢复到上一个版本。团队协作多人开发时所有人的代码都经过同样的验证流程。同时借助 PM2 的pm2 reload命令可以实现零停机部署避免在用户支付、提交等关键操作时因服务重启导致请求失败保障更好的用户体验和 SEO 排名。️ 第一道防线SSH 免密“三道安全门”在自动化部署中GitHub Actions 需要通过 SSH 连接你的服务器执行部署命令。为了安全性推荐使用 SSH 密钥认证而非密码。为了保护你的服务器与代码安全我们需要构筑“三道安全门”。第一道门专用部署密钥隔离不要复用你平时登录服务器的日常 SSH 密钥而是生成一把专用于 CI/CD 的密钥对。# 在本地终端生成专用于 GitHub Actions 部署的密钥对 ssh-keygen -t ed25519 -C github-actions-deploy -f ~/.ssh/github_actions_deploy # 直接回车不设置 passphrase自动化流程无法手动输入密码[7](ref)生成后将公钥添加到服务器的~/.ssh/authorized_keys文件中ssh-copy-id -i ~/.ssh/github_actions_deploy.pub your_useryour_vps_ip # 或者手动追加 cat ~/.ssh/github_actions_deploy.pub | ssh useryour-server cat ~/.ssh/authorized_keys [3](ref)[9](ref)第二道门GitHub Secrets 加密存储永远不要把私钥明文写在代码或 Workflow 文件里。GitHub Secrets 是专门存储敏感信息的加密存储。进入 GitHub 仓库的Settings → Secrets and variables → Actions → New repository secret依次添加以下变量SSH_HOST服务器 IP 地址SSH_USERSSH 登录用户名如 ubuntu, rootSSH_PRIVATE_KEY私钥全文内容需包含完整的-----BEGIN...-----END-----头尾SSH_PORTSSH 端口号默认 22 可省略第三道门最小权限隔离与主机指纹验证最小权限用户建议在服务器上创建一个专用的deploy用户仅授予其对项目目录的写权限而非直接使用 root 用户以限制破坏范围。主机指纹校验在 Workflow 中配置 SSH 连接时可加入主机指纹验证防止中间人攻击。⚙️ 第二道核心PM2 弹性管控与零停机重启PM2 (Process Manager 2) 是 Node.js 的生产级进程管理器它就像一个“监工”能确保你的应用始终保持可用。它在自动化部署中的核心价值包括崩溃自愈应用崩溃时自动重启。零停机部署使用pm2 reload命令PM2 会先启动新版本进程待其就绪后再平滑替换旧进程实现用户无感知的更新。日志与监控自动收集轮转日志并追踪 CPU 和内存消耗。在服务器首次部署时需要配置 PM2 开机自启npm install -g pm2 # 全局安装 cd /var/www/myapp pm2 start npm --name my-app -- start # 启动并命名应用 pm2 save # 保存当前进程列表 pm2 startup # 注册为系统服务确保服务器重启后自动拉起应用[3](ref)[8](ref)[9](ref) 实战编写 GitHub Actions 工作流完成上述准备后我们在项目根目录创建.github/workflows/deploy.yml文件编写自动化流水线。以下是一个通用的 Node.js 部署脚本name: Deploy to Server on: push: branches: - main # 仅当推送到 main 分支时触发 jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 cache: npm - name: Install dependencies run: npm ci - name: Run tests # 测试失败则中止部署 run: npm test - name: Build project run: npm run build - name: Deploy to VPS via SSH uses: appleboy/ssh-actionv1.0.3 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: ${{ secrets.SSH_PORT }} script: | cd /var/www/myapp git pull origin main npm ci --production # 使用 reload 实现零停机重启并更新环境变量 pm2 reload my-app --update-env echo ✅ 部署完成$(date) pm2 status工作流原理解析触发器 (on: push)代码推送到main分支后自动触发。CI 验证阶段在 GitHub 提供的 Runner 环境中执行npm ci、npm test和npm run build确保新代码不破坏已有功能。CD 部署阶段使用广泛认可的appleboy/ssh-action插件读取 Secrets 中的密钥连接服务器。远程执行脚本 (script)进入项目目录拉取最新代码、安装生产环境依赖最后使用pm2 reload平滑重启应用。 常见问题排查SSH 连接失败检查 GitHub Secrets 中的私钥格式是否完整包含头尾标记确认服务器防火墙开放了对应 SSH 端口。PM2 App not found 错误首次部署时 PM2 中没有该应用记录需先 SSH 登录服务器手动执行pm2 start命令初始化应用。命令找不到 (command not found)非交互式 SSH Shell 可能不会加载用户环境变量。如果遇到npm或pm2找不到可以在脚本中使用绝对路径或在服务器的 bash 配置中注释掉[ -z $PS1 ] return这一行。git pull权限错误确认服务器上的 Git 用户与authorized_keys中的密钥对应如果是私有仓库还需在服务器上配置具有只读权限的 Deploy Key。 总结通过结合GitHub Actions与PM2我们搭建了一套无需额外基建如 Jenkins、容器编排的轻量级自动化部署流水线。三道安全门保障了服务器的访问安全而 PM2 的弹性管控则赋予了应用零停机更新的能力。这套方案的优点在于完全免费公共仓库免费私有仓库每月有免费配额、安全可靠密钥不暴露在代码中、灵活扩展可随时加入测试、代码检查、多环境部署等步骤。现在你的发布流程已经从“手动 10 步”简化为了“git push一条命令”

相关新闻