Cloudflare Pages 是 Cloudflare 提供的静态网站托管与边缘部署平台:它把代码仓库接入自动构建流水线,构建产物直接分发到全球 300+ 边缘节点,免费套餐即提供无限带宽、无限站点与自动 HTTPS。Hugo 作为构建速度最快的静态站生成器(Go 编写,秒级构建数百页面),与 Cloudflare Pages 组合后,可以实现「git push → 数秒内全球边缘上线」的发布体验,是个人博客、文档站与 JAMstack 产品的高性价比首选。
对 Pages 平台本身架构不熟悉的读者,建议先读 Cloudflare Pages 完全指南:边缘托管、Functions 与全栈架构;想了解 Cloudflare 整体产品体系可参考 Cloudflare 详解:从 CDN 到全球边缘计算平台。本文聚焦一个具体场景:把 Hugo 站点干净利落地部署到 Cloudflare Pages。
为什么选择 Cloudflare Pages 托管 Hugo
静态站托管的可选项很多,简单对比一下主流方案:
| 平台 | 免费带宽 | 全球 CDN | 构建并发 | 备注 |
|---|---|---|---|---|
| Cloudflare Pages | 无限 | 300+ 节点 | 免费 1 并发 | 带宽按次不限量 |
| GitHub Pages | 软限制 100GB/月 | 有限节点 | 取决于 Actions 配额 | 不支持自定义 header |
| Vercel | 100GB/月 | 边缘网络 | 免费 1 并发 | 超出后费用较高 |
| Netlify | 100GB/月 | 边缘网络 | 免费额度有限 | 带宽计费较严格 |
Cloudflare Pages 的核心优势:
- 免费无限带宽:静态资源请求不计流量,对图片较多的文档站、作品集站点极友好,不存在「突然收到账单」的风险。
- 全球边缘节点:产物直接落在 Cloudflare 骨干网,国内访问延迟通常优于 GitHub Pages(虽然 Cloudflare 在国内没有官方节点,但其 Anycast 网络路由质量普遍更好)。
- Hugo 构建速度优势叠加:Hugo 本身构建极快,配合 Pages 的构建缓存,从 push 到上线常在 30 秒内完成。
- 原生支持
_headers/_redirects:缓存策略、安全头、301 跳转都能声明式配置,这是 GitHub Pages 做不到的。
关于各平台的更详细对比,可延伸阅读 Vercel 与 Netlify、Render、Railway、Cloudflare Pages 对比。
前置准备
动手之前,确认你的 Hugo 站点满足以下条件:
仓库结构
标准的 Hugo 仓库结构即可,Pages 会克隆整个仓库后在项目根目录执行构建:
my-site/
├── config.toml # 或 hugo.toml / hugo.yaml
├── content/
├── layouts/
├── static/
├── themes/ # 或 assets/ 里通过 Hugo Modules 引入
└── public/ # 构建产物目录(不要提交到 Git)
public/ 目录建议加入 .gitignore,构建产物让 Pages 生成即可。
主题引入方式
这是 Hugo 部署最容易踩的坑,三种方式按推荐程度排序:
- Hugo Modules(推荐):在
hugo.toml中用[[module.imports]]声明主题依赖,Pages 的构建环境自带 Go,构建时自动拉取,无需提交主题代码。 - 直接复制到
themes/目录:最稳妥,但主题更新需要手动同步。 - Git Submodule:可行,但 Pages 拉取 submodule 时需要确保仓库权限配置正确,私有 submodule 容易失败,详见后文排查章节。
baseURL 配置
baseURL 决定站内绝对路径资源的生成。可以先设置为你的正式域名(如 https://example.com/),Pages 会自动为每次部署注入正确的环境;更稳妥的做法是构建时通过环境变量覆盖,后文会讲。
分步实战:从仓库连接到首次上线
第一步:创建 Pages 项目并连接仓库
- 登录 Cloudflare Dashboard,左侧导航选择 Workers & Pages → Create → Pages → Connect to Git。
- 授权 Cloudflare 访问 GitHub(或 GitLab),选择你的 Hugo 站点仓库。
- 点击 Begin setup 进入构建设置页。
第二步:配置构建参数
在构建设置页填写:
- Framework preset(框架预设):选择 Hugo。选择后 Cloudflare 会自动填充默认构建命令和输出目录。
- Build command(构建命令):
hugo --gc --minify
参数说明:--gc 在构建后运行垃圾回收(清理缓存目录中不再使用的文件),--minify 压缩输出的 HTML/CSS/JS,可显著减小页面体积。
- Build output directory(输出目录):填
public。
如果你的主题依赖需要额外初始化(比如 Hugo Modules 首次拉取),可以写复合命令:
hugo mod get && hugo --gc --minify
实际上现代 Hugo 在构建时会自动解析模块依赖,多数情况下 hugo --gc --minify 就够了。
第三步:固定 HUGO_VERSION(关键步骤)
Cloudflare Pages 构建镜像内置了 Hugo,但内置版本通常偏旧(历史上长期停留在 0.5x 或更老的版本)。很多现代主题要求 Hugo 0.110+ 甚至 0.140+,版本不匹配是构建失败的头号原因。
在构建设置页找到 Environment variables(环境变量),添加:
HUGO_VERSION = 0.147.9
填入你本地开发时使用的 Hugo 版本(可用 hugo version 查看)。建议 Production 和 Preview 两个环境都设置,保证行为一致。
提示:如果构建日志出现「theme does not support Hugo version below X」之类的报错,九成是这里没设。
第四步:保存并部署
点击 Save and Deploy,Cloudflare 会拉取仓库、安装对应版本的 Hugo、执行构建并发布。构建日志实时可见,正常情况 1-2 分钟内完成。
部署成功后你会得到一个 https://<project-name>.pages.dev 的预览域名,立即全球可达。打开验证页面渲染、静态资源加载、搜索/短代码等功能是否正常。
自定义域名与 HTTPS
域名托管在 Cloudflare(推荐)
如果你的域名 DNS 已经托管在 Cloudflare,接入是一键式的:
- 进入 Pages 项目 → Custom domains → Set up a custom domain。
- 输入
example.com或www.example.com。 - Cloudflare 自动创建 CNAME 记录并签发 TLS 证书,几分钟内生效。
顺带建议:到 SSL/TLS 设置中将加密模式设为 Full (strict),并开启 Always Use HTTPS 与 HTTP/2、HTTP/3。
域名 DNS 在其他服务商
无法使用一键接入,需要手动添加 CNAME 记录:
类型: CNAME
主机记录: www(或 @,需服务商支持 CNAME flattening)
记录值: <project-name>.pages.dev
注意:根域名(apex domain)按 DNS 规范不能直接挂 CNAME,需服务商支持 CNAME Flattening 或 ALIAS/ANAME 记录(DNSimple、Namecheap 等都支持)。这也是把 DNS 迁到 Cloudflare 托管的又一个理由——它原生支持 apex CNAME。域名接入后的 CDN 缓存与 SSL 模式配置,见 自定义域名接入 Cloudflare:CDN 加速与缓存规则配置实战。
Preview 部署与分支预览工作流
Cloudflare Pages 的 Git 集成默认开启两种部署:
- Production 部署:推送到生产分支(默认
main)触发,绑定自定义域名。 - Preview 部署:任何其他分支的推送、以及 Pull Request 都会触发,生成独立的预览 URL,形如
https://<commit-hash>.<project-name>.pages.dev。
配合 Hugo 的工作流建议:
- 日常写作在
draft/xxx分支上进行,push 后自动获得预览链接,可用于校对和分享审稿。 - 合并到
main即上线。 - 如果文章带
draft: true,Hugo 默认不渲染,不需要额外配置。
需要注意的是,Preview 环境的 baseURL 与 Production 不同。如果主题用绝对路径生成资源,可以在构建命令中按环境覆盖:
hugo --gc --minify --baseURL "$CF_PAGES_URL"
CF_PAGES_URL 是 Pages 自动注入的环境变量,指向当前部署的完整 URL,能保证 Preview 环境下站内链接和资源路径全部正确。
进阶:_headers 与 _redirects
在 static/ 目录下放置 _headers 和 _redirects 文件,构建后它们会进入 public/ 根目录,由 Pages 边缘层直接执行,无需服务器逻辑。
_headers:缓存与安全头
# static/_headers
/assets/*
Cache-Control: public, max-age=31536000, immutable
/*.html
Cache-Control: public, max-age=0, must-revalidate
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
要点:Hugo 启用指纹(fingerprint)后,assets/ 下的静态资源带内容哈希,可以放心给一年强缓存;HTML 则用 must-revalidate 保证内容更新及时生效。安全头四件套是静态站的标配,成本为零。
_redirects:301 跳转
# static/_redirects
/old-post/* /new-post/:splat 301
/rss /index.xml 301
https://old-domain.com/* https://example.com/:splat 301
迁移旧站、改版 URL 结构时非常实用,跳转在边缘执行,延迟极低。
构建缓存加速
Pages 会缓存 node_modules 等目录加速后续构建。对于 Hugo 站点,主要耗时在主题模块拉取;使用 Hugo Modules 时,构建命令前加 hugo mod clean 并不必要——保持默认行为即可享受缓存。若构建变慢,可在项目设置的 Builds & deployments 中手动清除缓存后重试。
常见问题排查
Hugo 版本不匹配
症状:构建日志报 module "theme-xxx" not found、shortcode 解析失败、或主题明确要求更高版本。解决:设置 HUGO_VERSION 环境变量,与本地 hugo version 输出保持一致。
主题 submodule 拉取失败
症状:构建成功但页面完全无样式,日志里 themes/xxx 目录为空。解决:优先改用 Hugo Modules 引入主题;若坚持用 submodule,确保 .gitmodules 使用 HTTPS 地址而非 SSH 地址(Pages 构建环境没有你的 SSH key),私有 submodule 则需要改用 Modules 或内嵌主题代码。
baseURL 错误导致资源 404
症状:页面能打开但 CSS/JS 全部 404,浏览器控制台显示资源路径前缀错误。解决:检查 hugo.toml 的 baseURL 是否与当前访问域名一致;跨环境部署用 --baseURL "$CF_PAGES_URL" 覆盖。
构建超时
Pages 免费套餐构建时限为 20 分钟。Hugo 构建本身极快,超时通常是因为:图片资源巨大且开启了 Hugo 图像处理、或仓库体积过大(数 GB 的二进制资产)。解决:大图用外部图床或 Cloudflare R2,仓库里只保留必要资产;图像处理结果可通过 resources/_gen 目录缓存复用(需提交到仓库或接受首次构建较慢)。
常见问题(FAQ)
Cloudflare Pages 构建支持哪个 Hugo 版本?
Pages 构建镜像内置 Hugo,但版本偏旧且随镜像更新变化,不应依赖。官方推荐做法是通过 HUGO_VERSION 环境变量显式指定版本(如 0.147.9),构建系统会自动下载对应版本使用。建议固定一个与本地一致的版本,避免镜像更新导致构建行为漂移。
支持 Hugo Extended(Sass/SCSS)吗?
支持。通过 HUGO_VERSION 指定版本时,Cloudflare Pages 默认下载的是 Extended 版本,主题的 SCSS 资源管道(resources.ToCSS)可以正常工作。如果你的主题用 PostCSS,则需要走 Node 工具链,在构建命令里加上 npm install && npm run build 之类的步骤。
和 GitHub Pages 比哪个更适合 Hugo 博客?
大多数情况下 Cloudflare Pages 更优:免费带宽无上限、全球节点更多、支持 _headers/_redirects 自定义边缘行为、Preview 部署开箱即用。GitHub Pages 的优势仅在于与 GitHub 账号的零配置集成,但它不支持自定义响应头、缓存策略僵硬、且实际上有每月 100GB 的软带宽限制。
私有仓库可以部署吗?
可以。Cloudflare Pages 同时支持 GitHub 和 GitLab 的私有仓库,授权 OAuth 应用时勾选私有仓库访问权限即可,免费套餐没有此限制。
自定义构建命令怎么写?
在构建设置页的 Build command 中直接填写 shell 命令即可,支持 && 串联多条命令。常见例子:
hugo --gc --minify --baseURL "$CF_PAGES_URL"
如需在构建前生成内容(比如从 API 拉数据生成 markdown),可以在前面拼接脚本:
node scripts/fetch-content.js && hugo --gc --minify
构建环境预装 Node.js、Go、Python 等常用工具链,绝大多数静态站的构建需求都能覆盖。
相关阅读
- Cloudflare Pages 完全指南:边缘托管、Functions 与全栈架构
- Cloudflare 详解:从 CDN 到全球边缘计算平台
- Vercel 与 Netlify、Render、Railway、Cloudflare Pages 对比
- JAMstack 架构深度解析
- Cloudflare 专题导航
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。