本文档完整记录从 EdgeEver 笔记打标、经过 Blog MCP 推送 GitHub、再到 Vercel 自动构建 Hugo 博客并绑定 Cloudflare 自定义域名的全流程。重点复盘部署过程中因为 Framework 预设、环境变量版本号、Extended 依赖及快照机制导致的多次构建失败根因与彻底解决方案。


一、 整体技术架构与流转链路

[EdgeEver 笔记] (打标 blog / 博客 + 毫秒级锁定原始时间戳)
       │
       ▼ (Blog MCP / Cloudflare Worker: publish_post)
[GitHub 仓库] (kyaring/myblog -> content/posts/*.md)
       │
       ▼ (Webhook 自动触发推送事件)
[Vercel CI/CD] (注入 HUGO_VERSION 环境变量 -> Hugo Extended 编译静态站点 public/)
       │
       ▼ (CNAME 记录 DNS only)
[Cloudflare DNS] (blog.555586.xyz -> Vercel CDN 自动化 SSL)
  1. 源头管理:在 EdgeEver 中编写笔记,添加 blog 标签;
  2. 发布调度:Blog MCP 将笔记格式化为带 FrontMatter(title, date, tags, slug)的标准 Markdown,调用 GitHub API 提交并推送到仓库;
  3. 自动化部署:Vercel 监听 GitHub main 分支变动,自动拉取并根据环境变量指定版本运行 Hugo Extended 生成 HTML;
  4. 终端访问:Cloudflare DNS 解析至 Vercel,提供全球加速与自动化 HTTPS。

二、 核心部署踩坑复盘(为什么错了好几次?哪里出了错?)

在本次实际部署中,由于对 Vercel 构建镜像的预装机制、版本回退策略以及主题对 SCSS 的硬性依赖认识不足,导致连续构建失败、反复重试。以下为具体技术细节还原:

1. 致命坑一:仅选了 Hugo 预设依然报错(缺少环境变量 HUGO_VERSION)

  • 现象:在 Vercel 中把 Framework Preset 改为 Hugo 后,构建依然失败或直接警告/中断。
  • 根因:
    • Vercel 内置的 Hugo 默认预装版本极老(往往还是 0.5x 甚至更低古早版本),或者在某些纯静态环境未显式激活最新二进制。
    • 现代 Hugo 主题(如 PaperMod)使用了大量现代语法(如新版菜单、Taxonomies 配置、Page Bundles 结构),古早版本的 Hugo 遇到这些语法会直接 crash。
    • 光选 Framework 为 Hugo 是不够的,必须通过环境变量强行指定具体版本!
  • 彻底解决方案:
    • 进入 Vercel 项目:Settings -> Environment Variables;
    • 添加环境变量:
      • Key: HUGO_VERSION
      • Value: 0.131.0(或当前适配主题的稳定版本号,例如 0.125.0+);
      • Target: 全选 Production, Preview, Development。
    • 只有配置了这个环境变量,Vercel 在容器初始化阶段才会去动态拉取对应版本的二进制。

2. 致命坑二:Hugo 标准版 vs Extended(扩展版)编译失败

  • 现象:构建日志报错 execute of template failed,或提示 this feature is not available in your current Hugo version: you need the extended edition to compile SCSS/SASS。
  • 根因:
    • Hugo 分为普通版和 Extended(扩展版)。
    • PaperMod 等主流现代主题为了性能和定制化,采用 SCSS 来编译前端样式表。普通版 Hugo 根本没有内嵌 LibSass / CGO 依赖,无法处理 SCSS 文件。
  • 彻底解决方案:
    • Vercel 识别到 HUGO_VERSION 后默认拉取 Extended 版本;若使用自建 vercel.json 脚本,必须明确下载带有 extended 字样的发行包(如 hugo_extended_0.131.0_linux-amd64.tar.gz),不可下载普通包。

3. 致命坑三:初始导入识别为 Other 导致 command not found: hugo(Exit Code 127)

  • 现象:首次推送后,构建日志直接报 sh: line 1: hugo: command not found。
  • 根因:
    • Vercel 导入全新仓库时,如果根目录没有典型的前端配置文件(如 package.json),默认会被判定为 Other(纯静态)。
    • Other 的基础 Linux 容器中是完全干净的,根本没有安装任何静态生成器。
  • 彻底解决方案:
    • 在 Vercel 控制台 Settings -> General -> Framework Preset 中,将下拉框从 Other 强制改为 Hugo。

4. 致命坑四:Git Submodule 机制导致主题目录为空

  • 现象:Hugo 构建报错找不到主题模板(theme "PaperMod" not found),输出页面全白。
  • 根因:
    • 官方文档通常教人使用 git submodule add 引入主题。
    • CI/CD 在拉取仓库时如果没有配置递归拉取子模块(--recursive),拉取下来的 themes/PaperMod 只是一个空文件夹,导致模板引擎找不到任何布局文件。
  • 彻底解决方案:
    • 放弃 submodule 模式:直接将主题解压后,作为完整源码提交到仓库的 themes/PaperMod 目录中。这样无论任何平台拉取,主题文件都 100% 完整,绝对不会因为网络超时或子模块缺失而中断。

5. 致命坑五:构建失败引发的"旧快照回退"假象

  • 现象:在 GitHub 上明明已经删除了旧内容或提交了修复代码,但刷新 xxx.vercel.app 依然显示早期的内容,甚至一直吐出旧的 RSS XML。
  • 根因:
    • Vercel 生产保护机制:当最新的 Commit 发生构建报错(Failed / Error)时,生产环境绝不会宕机,而是自动锁定并持续提供上一次成功部署的历史镜像。
    • 这让人误以为是"CDN 强缓存"或者"修改没推送成功",但其实根因是最新提交构建挂了。
  • 彻底解决方案:
    • 排查问题时,第一优先级是检查 Vercel 控制台的 Deployments 列表。
    • 只有最新一次 Commit 呈现绿色的 Ready 状态,网站内容才会真正更新。

三、 规范化部署自检清单(一键避坑)

后续如果要新增站点或重新初始化博客,照着以下清单 1 次即可搞定:

检查项 正确配置 / 操作 说明
Framework Preset 选 Hugo 避免报 hugo: command not found
环境变量 HUGO_VERSION = 0.131.0 必须配置! 避免调用古老默认版本导致主题语法报错
主题存放方式 源码直传 themes/PaperMod 绝不用 git submodule,防拉取缺失
基础域名 baseURL hugo.toml 中填写自定义域名 保证 Canonical URL 和 RSS 链接正确
Cloudflare DNS CNAME 记录设为 DNS only(灰色云朵) 避免双重代理阻碍 Vercel 自动化 SSL 证书申请
验证标准 Vercel Deployments 状态为绿色 Ready 确保最新快照成功上线,而不是挂载历史旧包