记一次 Hexo 博客自动部署脚本排障之旅:从 Git 依赖污染到 rsync 权限陷阱
作为一名开发者,我用 Hexo 搭建了个人博客(xiaohuihui.cc),并编写了自动部署脚本,期望实现「Git 拉取代码 → Hexo 生成静态文件 → 同步到发布目录」的自动化流程。但脚本运行过程中接连踩坑,从 Git 依赖目录污染 到 rsync 权限错误,再到 宝塔 WebHook 执行环境异常,最终通过层层排查和优化,实现了脚本在宝塔 WebHook 中稳定运行。本文将完整复盘整个排障过程,并提供最终可直接使用的稳定版脚本。
一、需求背景
我的博客部署脚本核心需求:
- 拉取 Gitee 仓库最新博客源码;
- 执行缓存清理 + 静态文件生成,避免重复安装依赖;
- 将生成的
public目录同步到服务器发布目录; - 无需将生成的静态文件回推到 Git 仓库;
- 适配宝塔 WebHook 执行环境,确保自动触发时稳定运行。
最初的脚本看似逻辑完整,但实际运行时出现多个核心报错:Hexo 命令执行失败、rsync 同步报错(code 23)、宝塔 WebHook 执行显示「最终失败」但命令行正常。
二、问题排查与修复过程
问题 1:Hexo clean 失败 —— Git 仓库误提交 node_modules 导致环境污染
现象
脚本执行到 hexo clean 步骤时直接失败,Git 拉取日志中出现大量 mode change 100644 => 120000 记录,涉及 node_modules 下的多个文件。
根因分析
正常情况下,node_modules 属于项目依赖目录,应通过 .gitignore 忽略,不纳入 Git 版本控制。但仓库中误提交了 node_modules,且部分文件被标记为符号链接模式(120000),拉取代码后污染了 Hexo 执行环境,导致 Hexo 无法识别正确的可执行文件。
修复方案
清理本地异常依赖目录登录服务器,进入项目目录执行以下命令彻底清除异常文件:
1
2
3
4cd /www/wwwroot/node_js/hui_blog_hexo
rm -rf node_modules
git reset --hard origin/master
git clean -fd # 删除所有未被 Git 跟踪的文件完善 .gitignore 配置编辑项目根目录的
.gitignore文件,确保关键目录被忽略:1
2
3
4
5
6
7
8
9
10# Hexo 生成目录
public/
.deploy*/
.hexo/
# 依赖目录
node_modules/
# 日志与缓存文件
*.log
db.json
package-lock.json脚本优化:拉取代码时保留依赖目录脚本中
git clean命令增加排除参数,避免误删正常的node_modules:1
2git clean -fd --exclude="node_modules/" # 保留 node_modules 目录
git clean -fx --exclude="node_modules/"
问题 2:rsync 同步报错(code 23)—— 权限不足与参数格式错误
现象
解决 Hexo 执行问题后,rsync 同步步骤报错:
1 | rsync: delete_file: unlink(.user.ini) failed: Operation not permitted (1) |
同时出现 --safe-links: 未找到命令 的参数错误。
根因分析
- 参数格式错误:rsync 参数拆分行时未加反斜杠
\,导致参数被识别为独立命令; - 权限不足:宝塔面板生成的
.user.ini是保护文件,默认锁定权限,rsync 的--delete参数尝试删除时失败; - code 23 非致命:仅表示「部分文件属性未传输」,核心静态文件已同步完成。
修复方案
- 修正 rsync 参数格式:多行书写时末尾加
\,确保参数归属 rsync 命令; - 排除受保护文件:添加
--exclude=".user.ini"跳过.user.ini处理; - 优化权限修改:忽略
.user.ini的权限错误输出。
问题 3:宝塔 WebHook 执行异常 —— 环境变量与权限问题
现象
命令行执行脚本完全正常,但宝塔 WebHook 触发时显示「Hexo clean 最终失败」「执行失败」。
根因分析
- 环境变量缺失:宝塔 WebHook 精简环境中,
hexo全局命令无法加载 Node.js 模块; - 执行用户不一致:宝塔 WebHook 以
www/panel用户执行,无权限删除 root 创建的缓存文件; - 工作目录错误:默认执行目录非 Hexo 项目目录。
修复方案
- 强制指定环境变量:加载完整的系统 PATH 和 Node.js 模块路径;
- 提权执行:确保脚本以 root 用户运行;
- 跳过 hexo clean:手动删除缓存文件,替代
hexo clean命令; - 多重兜底:Hexo 生成和文件同步采用多方案兜底,提升稳定性。
问题 4:移除不必要的 Git 推送步骤
脚本最初包含 Git 提交 / 推送逻辑,触发两个错误:
fatal: unable to auto-detect email address:Git 身份未配置;Auth error: DeployKey does not support push code:DeployKey 无推送权限。
修复:直接移除所有 git add/git commit/git push 相关代码。
三、最终稳定版自动部署脚本
整合所有修复方案,适配宝塔 WebHook 环境的最终版脚本如下:
1 |
|
四、宝塔 WebHook 配置说明
进入宝塔面板 → 网站 → WebHook → 新增 / 编辑钩子;
「脚本内容」填写:
1
sudo bash /www/server/panel/plugin/webhook/script/你的脚本文件名.sh
「执行超时时间」设置为 60 秒(确保 Hexo 生成有足够时间);
保存后点击「测试触发」,正常输出如下:
1
2
3
4
5
6
7
8
92025-12-05 16:00:00
Start
项目目录已存在,正在更新仓库...
清除缓存...
生成静态文件...
清空发布目录旧文件...
复制到发布目录...
修复发布目录权限...
完成
五、排障总结与经验沉淀
- Git 仓库规范至关重要:永远不要将
node_modules、public等自动生成目录提交到 Git,避免跨环境部署的目录污染; - rsync 参数格式需严谨:多行书写参数时必须加反斜杠
\,同时注意排除宝塔保护文件(如.user.ini); - 宝塔 WebHook 环境适配核心:
- 强制指定完整环境变量,避免命令找不到;
- 提权以 root 用户执行,解决权限不足问题;
- 手动清理缓存替代
hexo clean,提升稳定性;
- 多重兜底提升鲁棒性:Hexo 生成和文件同步采用多方案兜底,单个方案失败自动切换,降低执行风险;
- 区分 rsync 错误类型:code 23 错误多为属性 / 权限问题,不影响核心文件传输,可通过
--ignore-errors忽略。
六、验证方法
脚本运行完成后,可通过以下命令验证静态文件同步结果:
1 | # 对比源目录和发布目录的首页文件 MD5 值 |
若两个 MD5 值一致,说明静态文件已成功同步,博客可正常访问。
通过本次排障,不仅修复了脚本的所有 bug,还深入理解了 Hexo 部署流程、Linux 命令细节和宝塔 WebHook 执行机制。该最终版脚本已在生产环境稳定运行,可直接复用至同类 Hexo 博客部署场景。







