背景
作为一个技术博客作者,每次写完文章都要手动执行一系列命令来部署:
1 2 3 4 5 6 7 8
| git add . git commit -m "new post" git push ssh server cd /path/to/blog git pull hexo clean && hexo generate
|
这个过程不仅繁琐,而且容易出错。更重要的是,每次部署都要手动操作,无法实现真正的持续集成。
为了解决这个问题,我引入了 OpenClaw 作为自动化助手,配合 GitHub 和 自动化部署脚本,实现了:
- ✅ 本地写完文章后一键提交
- ✅ GitHub 自动触发服务器拉取最新代码
- ✅ 自动执行 Hexo 生成和部署
- ✅ 性能优化(Gzip 压缩、图片优化、缓存策略)
- ✅ 部署完成后自动通知
本文将详细介绍整个自动化部署流程的实现细节。
什么是 OpenClaw
OpenClaw 是一个开源的 AI 代理框架,能够:
- 访问本地文件系统
- 执行 Shell 命令
- 控制浏览器
- 管理 Git 仓库
- 与外部服务(GitHub、QQ、飞书等)集成
简单来说,它就像一个住在你服务器上的智能助手,可以帮你自动完成各种重复性工作。
核心能力
| 能力 |
说明 |
| 文件操作 |
读写、编辑、创建文件 |
| 命令执行 |
运行任意 Shell 命令 |
| Git 集成 |
自动拉取、提交、推送代码 |
| 定时任务 |
通过 cron 或 heartbeat 定期检查 |
| 消息通知 |
支持 QQ、Telegram、飞书等 |
自动化部署架构
1 2 3 4 5 6 7 8 9 10
| ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 本地编辑 │────▶│ GitHub │────▶│ 服务器 │ │ (写文章) │ │ (代码仓库) │ │ (OpenClaw) │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ Webhook │ 自动部署 ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ 触发通知 │◀────│ 执行脚本 │ └─────────────┘ └─────────────┘
|
工作流程
- 本地写作:在本地编辑 Markdown 文章
- 提交推送:
git push 到 GitHub
- Webhook 触发:GitHub 通知服务器有新代码
- OpenClaw 执行:自动拉取代码并部署
- 性能优化:图片压缩、Gzip 启用
- 服务重启:Hexo 生成静态文件并重启服务
- 通知反馈:发送部署结果到 QQ/飞书
环境准备
服务器要求
- Linux (Ubuntu/CentOS/Debian)
- Node.js 18+
- Git
- OpenClaw
安装 OpenClaw
1 2 3 4 5
| npm install -g openclaw
openclaw init
|
配置 GitHub SSH
1 2 3 4 5 6
| ssh-keygen -t ed25519 -C "your_email@example.com"
cat ~/.ssh/id_ed25519.pub
|
部署脚本实现
核心部署脚本 (deploy.sh)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #!/bin/bash
set -e
export PATH="/root/.nvm/versions/node/v22.22.0/bin:$PATH"
BLOG_DIR="/root/.openclaw/workspace/blog" PUBLIC_DIR="$BLOG_DIR/public" PID_FILE="/tmp/blog-server.pid" PORT=8081 LOG_FILE="/var/log/blog-deploy.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" }
START_TIME=$(date +%s) log "========== 开始部署 =========="
cd "$BLOG_DIR"
log "拉取最新代码..." git pull origin main
log "清理旧文件..." npx hexo clean
log "生成静态文件..." npx hexo generate
log "重启博客服务..." if [ -f "$PID_FILE" ]; then OLD_PID=$(cat "$PID_FILE") kill "$OLD_PID" 2>/dev/null || true fi
fuser -k "$PORT/tcp" 2>/dev/null || true sleep 1
cd "$PUBLIC_DIR" nohup node server.js > /tmp/blog-server.log 2>&1 & NEW_PID=$! echo "$NEW_PID" > "$PID_FILE"
sleep 2 log "服务启动成功,PID: $NEW_PID"
END_TIME=$(date +%s) DURATION=$((END_TIME - START_TIME)) log "========== 部署完成 (耗时 ${DURATION}s) =========="
|
自动拉取脚本 (auto-deploy.sh)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #!/bin/bash
LOG_FILE="/var/log/auto-deploy.log" BLOG_DIR="/root/.openclaw/workspace/blog"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" }
cd "$BLOG_DIR"
git fetch origin main
LOCAL=$(git rev-parse HEAD) REMOTE=$(git rev-parse origin/main)
if [ "$LOCAL" != "$REMOTE" ]; then log "✅ 检测到更新,开始部署..." /root/.openclaw/workspace/blog/deploy.sh else log "没有更新,跳过部署" fi
|
GitHub Webhook 配置
创建 Webhook 服务
在服务器上创建 webhook-server.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| const http = require('http'); const { exec } = require('child_process'); const crypto = require('crypto');
const PORT = 9000; const SECRET = 'your_webhook_secret'; const DEPLOY_SCRIPT = '/root/.openclaw/workspace/blog/deploy.sh';
const server = http.createServer((req, res) => { if (req.method === 'POST' && req.url === '/webhook') { const signature = req.headers['x-hub-signature-256']; const body = req.body; const hmac = crypto.createHmac('sha256', SECRET); const digest = 'sha256=' + hmac.update(body).digest('hex'); if (signature !== digest) { res.writeHead(401); res.end('Invalid signature'); return; } exec(DEPLOY_SCRIPT, (error, stdout, stderr) => { if (error) { console.error(`部署失败:${error}`); return; } console.log(`部署成功:${stdout}`); }); res.writeHead(200); res.end('Deployment triggered'); } });
server.listen(PORT, () => { console.log(`Webhook 服务器运行在端口 ${PORT}`); });
|
启动 Webhook 服务
1 2 3 4 5
| npm install -g pm2 pm2 start webhook-server.js --name blog-webhook pm2 startup pm2 save
|
GitHub 配置
- 打开 GitHub 仓库 → Settings → Webhooks
- 点击 “Add webhook”
- 填写:
- Payload URL:
http://your-server:9000/webhook
- Content type:
application/json
- Secret: 与脚本中一致
- Events: 选择 “Just the push event”
- 点击 “Add webhook”
性能优化
1. Gzip 压缩
在 Nginx 配置中启用 Gzip:
1 2 3 4 5 6 7 8
| gzip on; gzip_vary on; gzip_min_length 1024; gzip_proxied any; gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; gzip_comp_level 6;
|
效果:HTML 文件从 40KB 压缩到 10KB,压缩比 75%
2. 图片优化
创建图片压缩脚本 (compress-images.sh):
1 2 3 4 5 6 7 8 9 10 11 12
| #!/bin/bash
API_KEY="your_tinypng_api_key"
for img in source/_posts/*.jpg; do curl -X POST \ -H "Authorization: Basic $API_KEY" \ -F "file=@$img" \ https://api.tinify.com/shrink \ -o "${img%.jpg}-compressed.jpg" done
|
效果:图片平均减小 60-70%
3. 浏览器缓存
1 2 3 4
| location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ { expires 30d; add_header Cache-Control "public, immutable"; }
|
4. 静态资源 CDN
将图片、CSS、JS 等静态资源托管到 CDN:
OpenClaw 自动化流程
配置 Heartbeat
在 HEARTBEAT.md 中添加定期检查任务:
1 2 3 4
| # 每 30 分钟检查一次博客部署状态 - 检查 GitHub 是否有新提交 - 检查服务是否正常运行 - 检查磁盘空间
|
OpenClaw 自动执行
OpenClaw 会定期:
- 检查 GitHub 仓库是否有新代码
- 如果有更新,自动执行
git pull
- 运行
hexo generate 生成静态文件
- 重启博客服务
- 发送部署通知
消息通知
部署完成后,OpenClaw 会自动发送通知:
1 2 3 4
| ✅ 博客部署成功 📝 提交:feat: 新增文章 ⏱️ 耗时:15s 🔗 访问:http://your-blog.com
|
实际使用流程
写作并发布
1 2 3 4 5 6 7 8 9 10
| hexo new post "我的新文章"
vim source/_posts/我的新文章.md
git add . git commit -m "new: 我的新文章" git push origin main
|
自动部署
推送后,整个过程自动进行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| GitHub 接收 push ↓ 触发 Webhook ↓ OpenClaw 执行部署脚本 ↓ git pull 拉取最新代码 ↓ hexo clean && hexo generate ↓ 重启博客服务 ↓ 发送 QQ/飞书通知 ↓ ✅ 部署完成!
|
全程无需人工干预,通常 15-30 秒 即可完成部署。
监控与日志
查看部署日志
1 2 3 4 5
| tail -f /var/log/blog-deploy.log
grep "部署完成" /var/log/blog-deploy.log | tail -10
|
服务状态检查
1 2 3 4 5 6 7 8
| ps aux | grep blog-server
netstat -tlnp | grep 8081
pm2 status
|
遇到的问题与解决方案
问题 1:Webhook 不触发
原因:服务器防火墙阻止了 9000 端口
解决:
1 2
| firewall-cmd --zone=public --add-port=9000/tcp --permanent firewall-cmd --reload
|
问题 2:部署后页面未更新
原因:浏览器缓存
解决:
- 强制刷新:
Ctrl + Shift + R
- 或在 Nginx 中配置缓存策略
问题 3:图片加载慢
原因:图片未压缩
解决:
- 使用
compress-images.sh 批量压缩
- 或配置 CDN 加速
总结
通过引入 OpenClaw 和自动化部署脚本,博客部署流程从手动 10+ 步骤简化为一键推送:
| 对比项 |
手动部署 |
自动化部署 |
| 步骤数 |
10+ |
1 |
| 耗时 |
5-10 分钟 |
15-30 秒 |
| 出错概率 |
高 |
极低 |
| 需要值守 |
是 |
否 |
核心优势
- 省时省力:写完文章直接 push,剩下的交给 OpenClaw
- 可靠性高:自动化脚本减少人为错误
- 性能优化:Gzip、图片压缩、缓存策略自动应用
- 可追溯:所有部署记录都有日志
- 可扩展:轻松添加新功能(如自动备份、监控告警)
未来规划
参考资源
如果你觉得这篇文章有帮助,欢迎 star 我的博客项目!