从一键脚本到全自动部署
起点:手动操作
最开始更新博客要走三步:
- 本地
hexo generate生成静态文件 scp上传到 ECS 服务器- SSH 上去
docker compose restart nginx
后来写了个 deploy-blog.sh 把三步合成一条命令,已经方便了很多。但还是得手动执行。
真正的自动化是什么?push 代码,剩下的全自动。
这就是今天要搞的——GitHub Actions CI/CD。
什么是 CI/CD
CI = 持续集成(Continuous Integration),代码 push 上去自动构建
CD = 持续部署(Continuous Deployment),构建完自动部署到服务器
一个典型的流程:
1 | |
你只需要 git push,剩下的机器帮你做。
实现步骤
1. 把博客源码托管到 GitHub
之前博客只有生成的静态文件在 GitHub Pages 上。现在把包括 Markdown、主题、配置在内的完整源码单独建一个仓库 blog-source。
1 | |
2. 配置 Secrets
GitHub Actions 的构建机器需要 SSH 连接你的 ECS。但密钥不能写在代码里公开,要用 GitHub Secrets:
仓库 → Settings → Secrets and variables → Actions → 添加三个 Secret:
| Secret 名 | 值 |
|---|---|
ECS_HOST |
服务器 IP |
ECS_USER |
SSH 用户名 |
SSH_KEY |
SSH 私钥完整内容 |
3. 编写工作流文件
在项目里创建 .github/workflows/deploy.yml:
1 | |
踩过的坑
坑 1:hexo 命令找不到
hexo generate 在 Actions 机器上报 Permission denied 或 command not found。
原因:本地装了 hexo-cli 全局包,但 Actions 机器上没有。
解决:用 npx hexo generate 并在项目里 npm install --save-dev hexo-cli。
坑 2:第三方 Action 版本号错误
easingthemes/ssh-deploy@v5 根本不存在。而且不同 Action 的 input 命名也不一样(REMOTE_HOST vs remoteHost)。
解决:放弃第三方 Action,直接用原生 scp 和 ssh 命令,简单可靠。
坑 3:Secrets 传参问题
用 env 块传 secret 到 shell 变量,结果 scp $HOST 时变量是空的。
解决:直接在命令里用 ${{ secrets.XXX }} 引用,不经过 env。
效果
现在更新博客的流程变成了:
1 | |
打开 GitHub Actions 页面能看到每次构建的完整日志,哪一步失败了点进去就能看到。
和之前的东西怎么配合
现在有三层自动化,层层递进:
| 层级 | 工具 | 触发方式 |
|---|---|---|
| 服务器监控 | check.sh + Glances | 随时手动 / cron 定时 |
| 数据安全 | backup.sh | cron 每天凌晨 3 点 |
| 代码部署 | GitHub Actions | git push 自动触发 |
这三层覆盖了一个运维最核心的日常:监控 → 备份 → 部署。
学到的概念
| 概念 | 解释 |
|---|---|
| CI | 持续集成:代码 push 后自动构建验证 |
| CD | 持续部署:构建成功后自动部署到目标环境 |
| GitHub Actions | GitHub 提供的 CI/CD 服务,免费额度够个人用 |
| Workflow | 工作流,定义在 .github/workflows/*.yml 里 |
| Job | 一次工作流运行,包含多个 Step |
| Step | 一个步骤,可以是 Action 或 shell 命令 |
| Secret | 加密变量,存密钥/密码,不会在日志里明文显示 |
| Runner | GitHub 提供的构建机器(ubuntu-latest) |
运维自动化不是一步到位的。先手写脚本,再一键脚本,最后才是 CI/CD。每一步都是在解决前一步的痛点。