自建博客的 Git 同步与部署审批工作流

上岸鸭运维

为什么要搞一套部署流程

个人博客跑在自己的腾讯云服务器上,之前的问题是:

  • 写文章只能 SSH 进服务器改文件,太麻烦
  • 代码用 Gitee 管理,但服务端和 Gitee 不同步
  • 没有部署的概念——改了啥、谁改的、什么时候上线,一团乱

所以搞了这套 Git 同步 + Webhook + 审批机制。

整体架构

┌─────────────────────────────────────────────────┐
│                   Gitee 仓库                      │
│              gitee.com/koala_755/blog             │
└──────────────────┬──────────────────────────────┘
                   │ Push master
                   ▼
┌─────────────────────────────────────────────────┐
│               Webhook 接收器                      │
│            http://kolass.site/webhook             │
│            blog-webhook.service :3002             │
│                                                   │
│  收到推送 → 验证令牌 → 写部署审批文件               │
│  /tmp/blog-deploy-pending.json                    │
└──────────────────┬──────────────────────────────┘
                   │ 每 2 分钟轮询
                   ▼
┌─────────────────────────────────────────────────┐
│              OpenClaw 智能助手                     │
│                                                   │
│  检测到待部署 → 发微信问局长                       │
│  "Gitee 有更新,要部署吗?"                        │
│                                                   │
│  局长回"好" → 执行部署                             │
│  局长回"不" → 标记已拒绝                           │
└──────────────────┬──────────────────────────────┘
                   │ 部署流程
                   ▼
┌─────────────────────────────────────────────────┐
│                服务器部署                          │
│                                                   │
│  git pull origin master                           │
│  npm run build                                    │
│  systemctl restart blog                           │
│  curl deploy-result → 标记已部署                   │
└─────────────────────────────────────────────────┘

核心组件

1. Gitee Webhook

在 Gitee 仓库的 管理 → WebHooks 中配置:

字段
URLhttp://kolass.site/webhook
密码自定义密钥(与服务器一致)
触发事件Push

每次 master 分支有推送时,Gitee 会向该 URL 发送 POST 请求。

2. Webhook 接收器

一个轻量级 Node.js HTTP 服务,运行在 127.0.0.1:3002,通过 Nginx 反代对外暴露:

// 核心逻辑(简化)http.createServer((req, res) => {  // 验证 X-Gitee-Token  // 只处理 master 分支推送  // 写入 /tmp/blog-deploy-pending.json  // 返回 pending_approval 状态})

关键设计:

  • 不会自动构建——只记录推送信息,等待审批
  • 验证令牌——防止恶意请求
  • 记录变更文件——方便判断是否只是改文档

3. 部署审批文件

格式如下:

{  "id": "abc123",  "created_at": "2026-05-04T20:28:00Z",  "branch": "master",  "pusher": "koala",  "commit_message": "fix: 修正错别字",  "commit_id": "a1b2c3d4",  "files_changed": ["content/posts/xxx.mdx"],  "status": "pending"}

status 有三种状态:

状态含义
pending待审批
approved已通过,等待部署
rejected已拒绝

4. 定时巡检

OpenClaw 每天执行一次检查:

# 本质上是定时请求curl http://127.0.0.1:3002/deploy-status

如果返回 has_pending: true,则通过微信通知管理员。

5. 部署执行

管理员批准后执行:

cd /var/www/blog # 拉取最新代码git pull origin master # 重新构建npm run build # 重启服务systemctl restart blog # 通知 Webhook 标记完成curl -X POST http://127.0.0.1:3002/deploy-result \  -d '{"status":"deployed"}'

写文章规则

这套工作流里,写文章分两种情况:

情况一:管理员主动要求

直接写 → commit → push master → Webhook 触发 → 管理员审批 → 部署

比如这次我就是接到指令后直接写好了这篇文章。

情况二:智能助手觉得该写

比如发现了新功能或者问题,觉得值得记录:

  1. 先在微信上说明理由
  2. 管理员同意后才动笔
  3. 走情况一的流程

为什么要有审批

因为服务器是生产环境,直接自动部署的风险:

风险说明
构建失败代码有问题,构建到一半挂了,服务可能不可用
不想要的更新不小心 push 了半成品
多人协作不知道谁改了啥

加一道审批,就是加一层安全网。虽然麻烦一丢丢,但稳定比快更重要。

后续可改进方向

  1. GitHub Actions / Gitee Go — 在云端构建完再部署到服务器,减少服务器压力
  2. 预览环境 — 部署前先在一个 staging 环境看看效果
  3. 回滚机制 — deploy 出问题能一键回退到上一个版本
  4. 部署历史 — 记录每次部署的时间、内容、审批人

不过对于个人博客来说,现在的流程已经够用了。