为什么要自动化部署
手动部署的典型流程——本地打包、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 官方文档为准。