Skip to content

个人博客自建指南(7):自动化部署 —— git push 直达线上(下)

回看上篇 !

承接上篇 继续:

四、ECS 上起 WebHook 接收服务

WebHook 的本质是 HTTP POST 请求。ECS 需要一个服务来接住它。我们用 Node.js 写一个极简的监听服务。

4.1 创建 WebHook 服务

bash
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) 命令查看后,进行替换。

javascript
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 启动服务

先用前台模式测试:

bash
node /home/ecs-user/webhook.js

终端输出 WebHook 监听在 http://0.0.0.0:9000 说明启动成功。按 Ctrl+C 停掉,然后改用 pm2 托管(更稳,支持开机自启)。

4.3 用 pm2 托管(推荐)

bash
# 安装 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 命令:

bash
# 查看运行状态
pm2 status

# 查看日志
pm2 logs blog-webhook

# 重启
pm2 restart blog-webhook

# 停止
pm2 stop blog-webhook

# 清空所有 pm2 日志
pm2 flush

# 只清空 blog-webhook 的日志
pm2 flush blog-webhook

4.4 修改 ECS的 Nginx 配置

在 Nginx 中加一段反代设置,让 WebHookhttps://jiejinx.cn/webhook,将部署服务暴露给码云进行推送触发。

bash
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:

bash
sudo nginx -t && sudo systemctl reload nginx

4.5 验证 WebHook 服务

先验证本机服务是否正常运行:

bash
# 自动提取 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 反代是否生效:

bash
curl -X POST "https://jiejinx.cn/webhook?token=$TOKEN"

如果返回 Deploy OK,说明反代配置正确,Gitee WebHook 可以通过 HTTPS 访问。

五、Gitee 仓库配置 WebHook

5.1 进入 WebHook 设置页

打开你的 Gitee 仓库 → 管理​ → WebHooks​ → 添加 WebHook。

5.2 填写配置

字段
URLhttp://你的ECS绑定的主站域名/?token=你的随机token(如 https://jiejinx.cn/webhook?token=$TOKEN
密码留空(我们已经在 URL 里带了 token)
事件勾选 Push 即可
激活✅ 勾选

查看token

bash
echo $(grep '^EXPECTED_TOKEN=' /home/ecs-user/deploy-blog.sh | cut -d'"' -f2)

5.3 测试 WebHook

点击 测试​ 按钮。Gitee 会向你的 ECS 发送一条测试 POST 请求。

在 ECS 上查看 pm2 日志:

bash
pm2 logs blog-webhook

如果看到 📦 收到 Gitee WebHook,开始部署... 且后续没有报错,说明 WebHook 通路已打通。

5.4 安全提示

  • token 要足够随机,可以用 openssl rand -hex 16 生成
  • 不要把 token 提交到 Git 仓库

六、本地工作流

配置完成后,你的日常更新流程简化为:

bash
# 写完文章,提交并推送
git add .
git commit -m "新增:树莓派 DDNS 配置"
git push

等待 20-40 秒,刷新 https://jiejinx.cn(你的主域名),新内容已上线。

七、日常维护

7.1 查看部署日志

bash
#  部署服务日志
pm2 logs blog-webhook

#  部署脚本日志
tail -20 /home/ecs-user/deploy.log

7.2 手动触发部署

如果 WebHook 因网络问题没触发,可以 SSH 登录 ECS 手动执行:

bash
# 自动提取 token 并验证
TOKEN=$(grep '^EXPECTED_TOKEN=' /home/ecs-user/deploy-blog.sh | cut -d'"' -f2)

bash /home/ecs-user/deploy-blog.sh $TOKEN

7.3 回滚

如果线上出了问题,本地回滚后推送即可:

powershell
git revert HEAD
git push

7.4 更新 ECS 上的 pnpm

bash
ssh ecs-user@你的ECS公网IP
pnpm add -g pnpm@latest

7.5 更换 token

如果怀疑 token 泄露:

  1. 修改 deploy-blog.shEXPECTED_TOKENnano /home/ecs-user/deploy-blog.sh
  2. **修改 webhook.js**中的 TOKENnano /home/ecs-user/webhook.js
  3. 重启 WebHook 服务pm2 restart blog-webhook
  4. 更新 Gitee WebHook URL 中的 token 参数

八、故障排查

8.1 WebHook 测试返回 401

  • 检查 URL 中的 token 是否与 deploy-blog.shwebhook.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 手动执行脚本,看具体错误:

bash
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 仓库配 WebHookpush 后通知 ECS
本地推送git push 完成上线

结合前6篇,你的个人博客自建之旅已全部闭环:

  1. 基础环境fnm + nodejs 环境搭建
  2. 开发环境vscode + vite 脚手架
  3. 项目管理git + 线上仓库
  4. 本地运行vitepress 搭建 + 第一篇博客
  5. 主题定制:品牌色、字体、Logo、导航栏
  6. 上线部署ECS + Nginx 手动部署
  7. 自动化部署Gitee + WebHook 一键上线(本篇)

从此你的博客进入了“自动挡”时代 —— 只管写文章,部署交给机器。开启你的内容创作之旅吧!

本专栏配套示例项目已上传gitee, 如有需要的读者可以拉取代码参考:项目示例

如果对服务器搭建感兴趣的话,也可以看看我的另一个系列:树莓派4B自建网页服务器指南