ARTICLE

GitHub Actions 自动部署到 DMIT:rsync 与回滚

用 GitHub Actions + rsync 自动部署应用到 DMIT:密钥配置、最小 sudo、原子发布与回滚。

为什么要自动化部署

手动部署的典型流程——本地打包、scp 上传、SSH 解压重启——步骤多、易漏、不可回溯。把部署交给 CI/CD(如 GitHub Actions)后,每次 push 自动完成测试、构建、上传与重启,全程有日志、可回滚。本文以 GitHub Actions + rsync 为例,演示把应用自动部署到 DMIT 云服务器。

方案选型

方案适用特点
rsync + SSH大多数 Web 应用简单直接,增量传输,无需服务器装额外组件
Git pull + hook小项目、内网工具服务器拉代码,需管理服务器上的密钥
Docker 镜像 + Compose容器化应用环境一致,配合《Docker 部署》使用

准备:部署专用账户与密钥

不要在 CI 里使用 root。创建受限的部署用户并配置密钥:

# 服务器上
adduser --disabled-password deploy
mkdir -p /home/deploy/.ssh
# 把公钥写入 authorized_keys(见下文 GitHub 密钥)
chmod 700 /home/deploy/.ssh
chown -R deploy:deploy /home/deploy/.ssh

# 应用目录归属
chown -R deploy:deploy /var/www/myapp

在 GitHub 仓库 Settings → Secrets 中添加:SSH_PRIVATE_KEY(私钥内容)、SSH_HOST、SSH_USER。私钥只在 CI 环境变量中出现,不进代码库。

GitHub Actions 工作流

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build
        run: npm ci && npm run build

      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts

      - name: Rsync to server
        run: rsync -avz --delete ./dist/ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/var/www/myapp/

      - name: Restart service
        run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} 'sudo systemctl restart myapp'

ssh-keyscan 首次连接自动记录主机指纹;生产环境建议把指纹预先固化到 known_hosts 以防中间人。

安全与回滚

  • 最小 sudo:只允许 deploy 免密执行 systemctl restart myapp:
    # /etc/sudoers.d/deploy
    deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp
  • 原子发布:先 rsync 到 /var/www/myapp-releases/时间戳/,再软链切换 current,失败一条命令回滚上一版本
  • 保留最近 5 个版本,清理更早的发布目录
  • 密钥轮换:定期更换部署密钥;泄露时在服务器删除对应公钥即可立即失效

常见问题

Permission denied (publickey)?

检查服务器上 ~/.ssh 权限(700/600)、authorized_keys 属主,以及 Actions 里私钥是否完整复制(含首尾行)。

rsync 卡住或超时?

确认防火墙放行 22 端口来源 IP(CI runner IP 不固定,不能只放行公司出口),并核对《安全清单》中的防火墙基线。

部署后服务没更新?

确认 restart 步骤真的执行了对应服务名;用 systemctl status myapp 与 journalctl -u myapp -f 验证(更多排查见《故障排查指南》)。

相关文章

《Docker 部署指南》、《安全检查清单》、《初次部署清单》。

本文核对日期:2026-08-18。Actions 语法以 GitHub 官方文档为准。

NEXT STEP

看完教程,选一台合适的 DMIT

用套餐快照按预算与线路筛选,或直接前往官网查看实时库存。

推广披露:通过链接购买可能为推荐者带来佣金,不会增加你的购买价格。