为什么要搭这个博客?

我想要一个足够轻、足够快、同时又方便长期维护的技术博客,用来记录 AI 使用经验、开发过程和各种问题排查。

对我来说,这个博客至少要满足四个条件:

  1. 写文章简单:最好就是写 Markdown
  2. 部署过程稳定:提交代码后可以自动上线
  3. 访问速度快:不想自己维护服务器
  4. 后续扩展容易:以后可以继续加搜索、SEO、评论等能力

在这些前提下,最后选择了 Hugo + GitHub + Cloudflare Pages 这套组合。

技术选型:为什么是这套组合?

Hugo:足够快,也足够简单

Hugo 是一个静态站点生成器,文章内容直接写成 Markdown,构建时生成纯静态页面。

它的优点很适合个人博客:

  • 构建速度快
  • 目录结构清晰
  • 不需要数据库
  • 主题生态成熟
  • 很适合托管到静态站点平台

GitHub:拿来托管源码和文章

博客的配置、主题、文章内容都放在 Git 仓库里,最大的好处是:

  • 每次改动都有记录
  • 可以随时回滚
  • 可以直接触发自动部署
  • 多设备维护也比较方便

Cloudflare Pages:省掉服务器运维

Cloudflare Pages 负责把构建产物发布出去。

我选择它主要是因为:

  • 配置简单
  • 有全球 CDN
  • 支持自定义域名
  • 免费额度对个人博客完全够用

主题:PaperMod

这个博客当前使用的是 PaperMod,它的特点是:

  • 页面简洁
  • 阅读体验好
  • 对技术博客比较友好
  • 搜索、归档、标签这些能力比较完整

第一步:初始化 Hugo 博客

最开始要做的是先把 Hugo 站点跑起来。

1. 安装 Hugo Extended

如果你用的是 PaperMod 这类依赖 SCSS 的主题,建议直接安装 Hugo Extended 版本。

安装完成后,可以先验证:

hugo version

如果出现命令不可用,通常是终端没有刷新,或者环境变量还没有生效。

2. 创建站点

hugo new site mimo-blog

创建完成后,会得到一个标准 Hugo 目录。

3. 添加主题

这里我接入的是 PaperMod 主题。接好以后,站点的整体结构大致会是这样:

mimo-blog/
├─ content/
├─ layouts/
├─ themes/
├─ archetypes/
├─ hugo.toml
└─ .github/

4. 本地预览

hugo server -D

这样就能先在本地看页面效果,调整配置和文章内容。

第二步:配置博客基础信息

博客能不能真正“像个博客”,关键就在 hugo.toml

这里我主要配置了这些内容:

  • baseURL:站点最终访问地址
  • languageCode / defaultContentLanguage:语言设置
  • title:站点标题
  • theme:使用的主题
  • menu.main:顶部导航菜单
  • params:主题参数,比如阅读时间、面包屑、代码复制按钮等

这一步很重要,因为后面 RSS、canonical 链接、站内绝对路径等都依赖 baseURL

如果这里一直保留占位域名,后面即使页面能打开,也会留下错误链接。

第三步:写文章的基本方式

Hugo 的文章本质上就是 Markdown 文件。

当前这个博客里,文章主要放在:

  • content/posts/
  • content/troubleshooting/

一篇文章通常至少会带这些 front matter:

---
title: "文章标题"
date: 2026-06-14T12:00:00+08:00
draft: false
tags: ["Hugo"]
categories: ["技术分享"]
summary: "一句话摘要"
---

写完以后,Hugo 会根据目录和文件名生成最终页面。

也就是说,后续新增文章时,最常见的动作其实只是:

  1. content/ 下新建一个 Markdown 文件
  2. 填好 front matter
  3. 写正文
  4. 本地构建验证
  5. 提交到 GitHub

第四步:把博客托管到 GitHub

本地博客能跑起来以后,下一步就是把它放进 GitHub 仓库。

我希望最后形成的是这种日常工作流:

git add .
git commit -m "new post"
git push origin main

为什么这样做很舒服?

因为文章、配置、部署流程都被版本化了:

  • 写文和改配置没有分离
  • 每次发布都可追踪
  • 出问题时更容易定位是哪次改动导致的

第五步:接入 Cloudflare Pages 自动部署

这个博客的部署并不是手工上传文件,而是依靠自动化流程完成的。

当前仓库里已经有 GitHub Actions 工作流:

  • push 到 main
  • 执行 hugo --minify
  • 调用 Cloudflare 的部署动作
  • 把生成的 public/ 发布到 Pages

这意味着以后发布文章的成本很低:

本地写好 → commit → push → 等待自动部署完成

相比手工上传静态文件,这种方式稳定很多,也更适合持续写作。

第六步:绑定自定义域名 blog.012332.xyz

博客能跑起来只是第一步,真正可长期使用,还是需要一个自己的域名。

这次绑定的是:

https://blog.012332.xyz/

大致过程如下:

  1. 在 Cloudflare Pages 项目里打开自定义域设置
  2. 添加 blog.012332.xyz
  3. 按向导完成 DNS 配置
  4. 等待 Cloudflare 验证域名
  5. 验证通过后启用 HTTPS

这一步最容易让人误判的地方是:

  • DNS 记录已经配好了
  • 但 Pages 状态还没立刻变成可用
  • 页面需要一点时间完成验证和生效

所以看到“验证中”并不一定代表失败,很多时候只是还没完全同步完成。

第七步:这次搭建里遇到的几个坑

1. Hugo 安装了,但命令不可用

这是最常见的问题之一,尤其是在 Windows 上。

通常原因有两个:

  • 终端没有重新打开
  • 环境变量还没刷新

2. baseURL 忘记改成正式域名

这类问题表面上看不一定会导致页面直接打不开,但会影响:

  • 文章 canonical
  • RSS 链接
  • 站内绝对路径
  • 部分分享链接

所以在域名正式启用后,最好尽快把 baseURL 改成线上真实地址。

3. 自定义域名不是提交后立刻生效

即使 DNS 配置正确,也可能要等待一段时间。

这个过程中最重要的是分清楚:

  • 是 DNS 没配好
  • 还是 Cloudflare 还在验证

这两种情况处理方式不一样。

第八步:现在这个博客是怎么发布文章的?

到现在,整个发布流程已经非常固定:

  1. content/posts/ 里写一篇 Markdown
  2. 检查 front matter 是否完整
  3. 本地运行 hugo --minify 验证构建
  4. 提交并推送到 main
  5. 等待 Cloudflare Pages 自动部署
  6. 在线访问页面确认是否正常

也就是说,后面新增文章时,已经不需要再手工折腾部署平台。

最终效果

现在这个博客已经具备这些能力:

  • 使用 Hugo 生成静态页面
  • 通过 GitHub 管理站点源码和文章
  • 通过 Cloudflare Pages 自动部署
  • 通过自定义域名 blog.012332.xyz 对外访问

对个人技术博客来说,这套方案已经足够轻量,也足够稳定。

总结

如果你也想搭一个维护成本低、发布流程清晰的技术博客,我会很推荐这条路线:

Hugo 负责生成内容,GitHub 负责版本管理,Cloudflare Pages 负责自动部署,自定义域名负责最终对外展示。

它的好处不是“花哨”,而是整个流程很顺:

  • 写作简单
  • 发布简单
  • 运维负担低
  • 后续扩展空间也足够

对我来说,这个博客搭建完成后,真正重要的事情就只剩下一件:

持续写下去。