本文汇总 Hexo 博客的部署运维要点,涵盖服务器端自动化部署(Termux proot-distro Ubuntu)与 Windows 本地端部署脚本。
目录
1. 服务器端自动化部署(Termux Ubuntu) 1.1 脚本整体功能 适用于 Termux proot-distro Ubuntu 环境,全自动流程:
DNS 异常自动修复
Gitee 私有仓库 pull / clone 源码
智能判断依赖变更 ,不每次重复安装依赖
保留 hexo clean && hexo generate 完整编译
强制校验编译结果,杜绝空目录报错
安全同步 public 静态文件到 Nginx 站点目录
智能 Nginx 管理:运行则重载、未运行则启动
1.2 本次解决的核心报错(重点) 报错 :
cp: cannot stat '/xxx/public/*': No such file or directory
根本原因 :
hexo clean 会清空 public 目录,如果 hexo generate 编译异常/警告中断,public 为空,* 通配符匹配失败直接报错。
最终两套防护方案 :
编译后强制校验 public/index.html,不存在直接终止脚本
复制命令由 public/* 改为 public/.,空目录也不会报错
1.3 依赖优化机制(关键改进) 不再无脑 pnpm install,采用 md5 哈希对比 :
监控文件:package.json、pnpm-lock.yaml
文件无变化 → 跳过安装,速度极快
文件变更(插件新增/升级/版本变动)→ 自动执行 pnpm install
首次运行 → 自动安装依赖
缓存文件:zzcblog-source/.pkg.md5sum
手动强制重装依赖:rm .pkg.md5sum 再运行脚本
1.4 Nginx 智能启停逻辑
检测到 Nginx 正在运行 → nginx -s reload 平滑重载
Nginx 未运行 → nginx -c /etc/nginx/nginx.conf 2>/dev/null 静默启动
1.5 已关闭功能
关闭 Git 自动安装(环境预装 Git)
关闭强制 pnpm install,改为按需检测
1.6 最终完整脚本(可直接 cat 生成) cat > deploy-blog.sh <<'EOF' set -euo pipefailREPO_URL="${REPO_URL:-git@gitee.com:wszack/zzcblog-source.git} " REPO_BRANCH="${BRANCH:-main} " CLONE_DIR="/root/zzcblog-source" WEB_TARGET="/var/www/hexo-blog" LOG_FILE="/var/log/deploy-blog.log" NGINX_CONF="/etc/nginx/nginx.conf" PKG_HASH_FILE="${CLONE_DIR} /.pkg.md5sum" log () { echo "[$(date '+%Y-%m-%d %H:%M:%S') ] $*" | tee -a "$LOG_FILE " } cleanup () { log "脚本执行结束" } trap cleanup EXITfix_dns_if_needed () { if ! ping -c 1 -W 2 mirrors.aliyun.com >/dev/null; then log "DNS解析异常,切换公共DNS" echo "nameserver 8.8.8.8" > /etc/resolv.conf echo "nameserver 223.5.5.5" >> /etc/resolv.conf fi } log "==============================================" log " Hexo 全自动部署脚本启动" log "==============================================" fix_dns_if_needed log "[1/4] 处理源码仓库" if [ -d "$CLONE_DIR /.git" ]; then log "仓库已存在,执行 git pull 更新" cd "$CLONE_DIR " git stash push -m "auto-stash before pull" 2>/dev/null || true git fetch origin git checkout "$REPO_BRANCH " git pull origin "$REPO_BRANCH " git stash pop 2>/dev/null || true log "源码更新完成" else log "首次克隆私有仓库" rm -rf "$CLONE_DIR " git clone -b "$REPO_BRANCH " "$REPO_URL " "$CLONE_DIR " log "克隆完成" fi log "[2/4] 检测依赖文件变更" cd "$CLONE_DIR " CURRENT_HASH=$(md5sum package.json pnpm-lock.yaml 2>/dev/null || echo "missing" ) if [ -f "$PKG_HASH_FILE " ]; then LAST_HASH=$(cat "$PKG_HASH_FILE " ) if [ "$CURRENT_HASH " != "$LAST_HASH " ]; then log "依赖已变更,执行 pnpm install" pnpm install echo "$CURRENT_HASH " > "$PKG_HASH_FILE " else log "依赖无变动,跳过安装" fi else log "首次初始化依赖,执行 pnpm install" pnpm install echo "$CURRENT_HASH " > "$PKG_HASH_FILE " fi log "[3/4] 执行 Hexo 清理+编译" cd "$CLONE_DIR " hexo clean && hexo generate if [ ! -f "${CLONE_DIR} /public/index.html" ];then log "❌ Hexo 编译失败,无 index.html,终止部署" exit 1 fi log "✅ Hexo 编译成功" log "[4/4] 同步静态资源至 Nginx 目录" mkdir -p "$WEB_TARGET " cp -r "${CLONE_DIR} /public/." "${WEB_TARGET} /" chown -R root:root "$WEB_TARGET " if pgrep -x "nginx" > /dev/null; then log "Nginx 运行中,执行重载" nginx -s reload else log "Nginx 未运行,启动 Nginx" nginx -c "${NGINX_CONF} " 2>/dev/null fi log "" log "✅ 博客部署完成!访问地址:http://127.0.0.1:8080" log "==============================================" EOF
1.7 使用命令 生成脚本 + 授权 + 运行:
chmod +x deploy-blog.sh./deploy-blog.sh
1.8 手动重置依赖缓存(备用) rm /root/zzcblog-source/.pkg.md5sum
1.9 脚本最终特性汇总
✅ 保留 hexo clean 完整清理编译
✅ 解决 public 空目录 cp 报错
✅ 智能依赖检测,不重复安装
✅ 编译失败自动终止,不破坏站点
✅ Nginx 智能启停/重载
✅ 自动 DNS 修复
✅ 完整日志记录
✅ proot Ubuntu 权限完美适配
2. Windows 本地部署脚本 2.1 版本 1(未设置全局 Git,使用环境变量方案) @echo off echo 清理旧静态文件(加载 _config.github.yml 配置)...set GIT_AUTHOR_NAME=zzc-blogset GIT_AUTHOR_EMAIL=2542434555 @qq.comset GIT_COMMITTER_NAME=zzc-blogset GIT_COMMITTER_EMAIL=2542434555 @qq.comcall hexo clean --config _config.yml,_config.github.ymlif %errorlevel% neq 0 ( echo 清理文件失败! pause exit /b %errorlevel% ) echo 正在生成静态文件(加载 _config.github.yml 配置)...call hexo g --config _config.yml,_config.github.ymlif %errorlevel% neq 0 ( echo 静态文件生成失败! pause exit /b %errorlevel% ) echo 开始部署至Github Pages...call hexo d --config _config.yml,_config.github.ymlif %errorlevel% neq 0 ( echo 部署失败! pause exit /b %errorlevel% ) echo ✅ 部署完成!pause
2.2 版本 2(已配置全局 Git,精简版本) @echo off echo 清理旧静态文件(加载 _config.github.yml 配置)...call hexo clean --config _config.yml,_config.github.ymlif %errorlevel% neq 0 ( echo 清理文件失败! pause exit /b %errorlevel% ) echo 正在生成静态文件(加载 _config.github.yml 配置)...call hexo g --config _config.yml,_config.github.ymlif %errorlevel% neq 0 ( echo 静态文件生成失败! pause exit /b %errorlevel% ) echo 开始部署至Github Pages...call hexo d --config _config.yml,_config.github.ymlif %errorlevel% neq 0 ( echo 部署失败! pause exit /b %errorlevel% ) echo ✅ 部署完成!pause
关于 hexo d 身份报错(Author identity unknown)的详细解决方案,见《Git 配置笔记》。
3. 部署故障处理
部署报错优先执行清理缓存:
yaml 配置报错:禁止使用 Windows 记事本编辑,避免隐形特殊字符、中文空格、Tab 制表符
Hexo 编译参数格式说明:hexo g --config _config.yml,_config.github.yml
主配置在前,扩展配置在后,后者覆盖 同名 url 等参数