个人博客自建指南(7):自动化部署 —— git push 直达线上(下)
回看上篇 !
承接上篇 继续:
四、ECS 上起 WebHook 接收服务
WebHook 的本质是 HTTP POST 请求。ECS 需要一个服务来接住它。我们用 Node.js 写一个极简的监听服务。
4.1 创建 WebHook 服务
nano /home/ecs-user/webhook.js复制粘贴以下内容:
⚠️ 复制前修改:
// ⚠️ 跟 deploy-blog.sh 里的 EXPECTED_TOKEN 一致const TOKEN = '你的随机token';
这里的随机token通过执行echo $(grep '^EXPECTED_TOKEN=' /home/ecs-user/deploy-blog.sh | cut -d'"' -f2)命令查看后,进行替换。
const http = require('http');
const { exec } = require('child_process');
const PORT = 9000;
// ⚠️ 跟 deploy-blog.sh 里的 EXPECTED_TOKEN 一致
const TOKEN = '你的随机token';
const SCRIPT = '/home/ecs-user/deploy-blog.sh';
//并发标记
let deploying = false;
const server = http.createServer((req, res) => {
if (req.method !== 'POST') {
res.writeHead(405);
res.end('Method Not Allowed');
return;
}
// 从 URL query 中取 token
const url = new URL(req.url, `http://${req.headers.host}`);
const token = url.searchParams.get('token');
if (token !== TOKEN) {
res.writeHead(401);
res.end('Unauthorized');
return;
}
// ✅ 先立即回复 Gitee,避免超时重试
if (deploying) {
//部署脚本 并发拦截
res.writeHead(200);
res.end('Deploy Skip');
console.log(`🛑 另一部署正在进行,跳过本次请求`);
return;
}else{
//开始部署
deploying = true;
res.writeHead(200);
res.end('Deploy OK');
console.log('📦 收到 Gitee WebHook,开始部署...');
}
// ✅ 后台执行部署脚本(不阻塞响应)
exec(`bash ${SCRIPT} ${TOKEN}`, (error, stdout, stderr) => {
if (error) {
console.error('❌ 部署失败:', stderr);
}else{
console.log(stdout);
console.log('🎉 部署完成');
}
// 无论成功还是失败,都要重置 deploying
deploying = false;
});
});
server.listen(PORT, '0.0.0.0', () => {
console.log(`WebHook 监听在 http://0.0.0.0:${PORT}`);
});保存退出( ctrl+o -> Enter -> ctrl+x )
4.2 启动服务
先用前台模式测试:
node /home/ecs-user/webhook.js终端输出 WebHook 监听在 http://0.0.0.0:9000 说明启动成功。按 Ctrl+C 停掉,然后改用 pm2 托管(更稳,支持开机自启)。
4.3 用 pm2 托管(推荐)
# 安装 pm2
pnpm add -g pm2
# 启动 WebHook 服务
pm2 start /home/ecs-user/webhook.js --name blog-webhook
# 保存进程列表
pm2 save
# 配置开机自启
pm2 startup执行 pm2 startup 后,终端会输出一行命令,复制->粘贴->执行 即可。如:sudo env PATH=$PATH:/home/ecs......
常用 pm2 命令:
# 查看运行状态
pm2 status
# 查看日志
pm2 logs blog-webhook
# 重启
pm2 restart blog-webhook
# 停止
pm2 stop blog-webhook
# 清空所有 pm2 日志
pm2 flush
# 只清空 blog-webhook 的日志
pm2 flush blog-webhook4.4 修改 ECS的 Nginx 配置
在 Nginx 中加一段反代设置,让 WebHook 走 https://jiejinx.cn/webhook,将部署服务暴露给码云进行推送触发。
sudo nano /etc/nginx/conf.d/jiejinx.cn.conf在 server 块中添加:
server {
# ...其他配置
location /webhook {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}保存退出( ctrl+o -> Enter -> ctrl+x )
重载 Nginx:
sudo nginx -t && sudo systemctl reload nginx4.5 验证 WebHook 服务
先验证本机服务是否正常运行:
# 自动提取 token 并验证
TOKEN=$(grep '^EXPECTED_TOKEN=' /home/ecs-user/deploy-blog.sh | cut -d'"' -f2)
curl -X POST "http://127.0.0.1:9000/?token=$TOKEN"
# 如果返回 Deploy OK,说明服务正常。再验证 Nginx 反代是否生效:
curl -X POST "https://jiejinx.cn/webhook?token=$TOKEN"如果返回 Deploy OK,说明反代配置正确,Gitee WebHook 可以通过 HTTPS 访问。
五、Gitee 仓库配置 WebHook
5.1 进入 WebHook 设置页
打开你的 Gitee 仓库 → 管理 → WebHooks → 添加 WebHook。
5.2 填写配置
| 字段 | 值 |
|---|---|
| URL | http://你的ECS绑定的主站域名/?token=你的随机token(如 https://jiejinx.cn/webhook?token=$TOKEN) |
| 密码 | 留空(我们已经在 URL 里带了 token) |
| 事件 | 勾选 Push 即可 |
| 激活 | ✅ 勾选 |
查看token
echo $(grep '^EXPECTED_TOKEN=' /home/ecs-user/deploy-blog.sh | cut -d'"' -f2)5.3 测试 WebHook
点击 测试 按钮。Gitee 会向你的 ECS 发送一条测试 POST 请求。
在 ECS 上查看 pm2 日志:
pm2 logs blog-webhook如果看到 📦 收到 Gitee WebHook,开始部署... 且后续没有报错,说明 WebHook 通路已打通。
5.4 安全提示
- token 要足够随机,可以用
openssl rand -hex 16生成 - 不要把 token 提交到 Git 仓库
六、本地工作流
配置完成后,你的日常更新流程简化为:
# 写完文章,提交并推送
git add .
git commit -m "新增:树莓派 DDNS 配置"
git push等待 20-40 秒,刷新 https://jiejinx.cn(你的主域名),新内容已上线。
七、日常维护
7.1 查看部署日志
# 部署服务日志
pm2 logs blog-webhook
# 部署脚本日志
tail -20 /home/ecs-user/deploy.log7.2 手动触发部署
如果 WebHook 因网络问题没触发,可以 SSH 登录 ECS 手动执行:
# 自动提取 token 并验证
TOKEN=$(grep '^EXPECTED_TOKEN=' /home/ecs-user/deploy-blog.sh | cut -d'"' -f2)
bash /home/ecs-user/deploy-blog.sh $TOKEN7.3 回滚
如果线上出了问题,本地回滚后推送即可:
git revert HEAD
git push7.4 更新 ECS 上的 pnpm
ssh ecs-user@你的ECS公网IP
pnpm add -g pnpm@latest7.5 更换 token
如果怀疑 token 泄露:
- 修改
deploy-blog.sh中的EXPECTED_TOKEN:nano /home/ecs-user/deploy-blog.sh - **修改
webhook.js**中的TOKEN:nano /home/ecs-user/webhook.js - 重启 WebHook 服务:
pm2 restart blog-webhook - 更新
Gitee WebHook URL中的token参数
八、故障排查
8.1 WebHook 测试返回 401
- 检查 URL 中的 token 是否与
deploy-blog.sh和webhook.js中的一致 - 检查 token 是否包含特殊字符(如
&、?),如果有需要对URL编码
8.2 WebHook 测试返回 502
检查 ECS 上 webhook.js 是否在运行:pm2 status 检查端口 9000 是否被防火墙阻挡:ECS 安全组需放行 9000 端口(如果没配 Nginx 反代) 如果配了 Nginx 反代,检查 Nginx 是否正常运行:sudo systemctl status nginx
8.3 部署脚本执行报错
登录 ECS 手动执行脚本,看具体错误:
TOKEN=$(grep '^EXPECTED_TOKEN=' /home/ecs-user/deploy-blog.sh | cut -d'"' -f2)
bash /home/ecs-user/deploy-blog.sh $TOKEN常见原因:
pnpm未安装或版本不对node版本不对Gitee仓库地址写错- 私有仓库未配置部署密钥
7.4 部署成功但页面没更新
- 检查
rsync的目标路径是否正确:/var/www/html/blog/ - 检查 Nginx 的
root配置是否指向该目录 - 清除浏览器缓存后重试
九、总结
这篇我们实现了:
| 步骤 | 说明 |
|---|---|
| ECS 上安装 Node.js + pnpm | 为自动化构建提供运行时环境 |
| ECS 上写部署脚本 | 拉代码 → 构建 → 同步 |
| Nginx 反代 | 隐藏端口,走 HTTPS |
| ECS 上起 WebHook 服务 | 接收 Gitee 的通知,触发部署 |
| Gitee 仓库配 WebHook | push 后通知 ECS |
| 本地推送 | git push 完成上线 |
结合前6篇,你的个人博客自建之旅已全部闭环:
- 基础环境:
fnm + nodejs环境搭建 - 开发环境:
vscode + vite脚手架 - 项目管理:
git+ 线上仓库 - 本地运行:
vitepress搭建 + 第一篇博客 - 主题定制:品牌色、字体、
Logo、导航栏 - 上线部署:
ECS + Nginx手动部署 - 自动化部署:
Gitee + WebHook一键上线(本篇)
从此你的博客进入了“自动挡”时代 —— 只管写文章,部署交给机器。开启你的内容创作之旅吧!
本专栏配套示例项目已上传gitee, 如有需要的读者可以拉取代码参考:项目示例
如果对服务器搭建感兴趣的话,也可以看看我的另一个系列:树莓派4B自建网页服务器指南