在 CI/CD(如 GitHub Actions)高度普及的今天,选择“手动编译 + 强制推送”的博客部署方式似乎显得有些原始。但对于个人技术博客而言,这种方式让我能最大程度地掌控发布的每一个细节,同时也实现了“源码”与“静态产物”的物理隔离,避免了自动化脚本黑盒带来的调试焦虑。
本文不仅是简单的安装指南,更是从环境构建到灾难恢复的全流程备忘录。文章重点解决了Hugo Extended 版本的环境依赖(针对 PaperMod 等需要 SCSS 编译的主题),详细拆解了基于 Git 的双仓库管理策略,并补充了在更换设备时如何通过子模块递归克隆实现“一键还原”的方案。
1. 核心环境与依赖
- 操作系统:Windows 10/11 + WSL 2 (Ubuntu 24.04 LTS)
- 生成器:Hugo (Extended Version)
- 关键点:由于我使用的 PaperMod 主题依赖 SCSS 编译和 PostCSS 功能,必须使用 Hugo Extended 版本,标准版会报错。
- 版本控制:Git
- 部署策略:本地编译
public目录 ->git push -f覆盖远端 GitHub Pages 仓库。
2. 环境搭建:安装 Hugo Extended
Ubuntu 默认 apt 源中的 Hugo 版本通常非常老旧且不包含 Extended 功能,因此强烈建议直接下载官方 .deb 包安装。
2.1 下载与安装
访问 Hugo GitHub Releases 页面获取最新版本链接(以下以 0.154.5 为例):
# 1. 下载 Extended 版本的 .deb 包 (请根据最新版本号修改 URL)
wget wget https://github.com/gohugoio/hugo/releases/download/v0.154.5/hugo_extended_0.154.5_linux-amd64.deb
# 2. 执行安装
sudo dpkg -i hugo_extended_0.154.5_linux-amd64.deb
2.2 验证安装
安装完成后,必须验证版本是否包含 extended 标识:
hugo version
# 预期输出示例:
# hugo v0.125.0-5nd7s8d6+extended linux/amd64
注意:一定要看到
extended字样才算成功。
3. 项目初始化与配置
3.1 创建站点
使用 Git Submodule 管理主题,保持项目结构整洁。
# 创建站点
hugo new site myblog
cd myblog
# 初始化 Git (源码库)
git init
# 拉取 PaperMod 主题
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
3.2 关键配置 (hugo.toml)
编辑根目录下的 hugo.toml。这是构建时的唯一真理来源。
baseURL = "https://yourname.github.io/" # ⚠️ 必须与 GitHub Pages 地址完全一致,且以 / 结尾,yourname 是 GitHub 用户名
languageCode = "zh-cn"
title = "Tech Memo"
theme = "PaperMod"
[params]
defaultTheme = "auto"
ShowCodeCopyButtons = true
4. 日常写作与发布流水线
这是每次更新文章时需要严格执行的标准操作序列。
第一步:新建文章
使用 Hugo CLI 生成带标准 Front Matter 的文件,避免手动创建出错。
hugo new content posts/my-new-post.md
使用编辑器打开并修改元数据:
- draft: 将
true改为false(否则生成时会被跳过)。 - date: 格式必须严格遵守
YYYY-MM-DD(如2024-05-21)。
第二步:本地预览
启动本地服务器,实时查看渲染效果。
hugo server -D
# -D 参数表示包含草稿 (Drafts),方便预览还未发布的文章
浏览器访问 http://localhost:1313 检查排版。
第三步:清理与编译 (Build)
确认无误后,停止预览,开始生成最终网页。为了防止历史残留文件导致的问题,建议先清理后构建。
# 1. 彻底删除旧的构建目录
rm -rf public
# 2. 执行静态编译
hugo
执行成功后,根目录下会重新生成一个 public 文件夹,其中包含了网站所有的静态资源(HTML/CSS/JS)。
第四步:推送部署 (Deploy)
⚠️ 关键步骤:我们将 public 目录视为一个独立的、临时的 Git 仓库,每次都强制推送到 GitHub Pages。
# 1. 进入静态资源目录
cd public
# 2. 初始化为全新仓库 (抛弃旧的历史)
git init
git branch -M main
# 3. 关联远程仓库 (GitHub Pages 仓库)
git remote add origin https://github.com/yourname/yourname.github.io.git
# 4. 暂存并提交
git add .
git commit -m "Deploy: update blog content $(date '+%Y-%m-%d %H:%M')"
# 5. 强制推送到 GitHub
# 说明:因为是全新 init 的仓库,与远程历史不符,必须使用 -f (--force)
git push -u -f origin main
5. 核心原理:双仓库策略
为了保证数据安全和逻辑清晰,我采用了源码与产物分离的策略:
-
源码仓库 (Source):
- 位置:本地
~/myblog(推荐推送到 GitHub 私有仓库备份)。 - 内容:Markdown 源码、配置文件、原始图片。
- 设置:在
.gitignore中添加/public,防止编译产物污染源码库。
- 位置:本地
-
发布仓库 (Pages):
- 位置:GitHub 上的
yourname.github.io。 - 内容:仅包含
public文件夹内的 HTML/CSS/JS。 - 逻辑:这是源码的“快照”。通过
rm -rf public和git push -f,我们保证每次发布的都是最纯净的版本,且不需要在发布仓库保留冗余的 Commit 历史。
- 位置:GitHub 上的
6. 避坑指南
-
Extended 版本报错
- 如果在执行
hugo时出现MIME type、PostCSS或TOCSS相关的错误,99% 是因为你装成了 Hugo 标准版。请重新参照第 2 节安装 Extended 版。
- 如果在执行
-
样式丢失 (CSS 404)
- 部署后如果页面只有文字没有排版,检查
hugo.toml中的baseURL。 - 它必须完全匹配你的 GitHub Pages URL(例如
https://username.github.io/),末尾的斜杠/最好加上。
- 部署后如果页面只有文字没有排版,检查
-
文章不显示
- 检查文章头部的
draft: true是否改为了false。 - 检查
date是否是未来时间(Hugo 默认不渲染未来日期的文章)。
- 检查文章头部的
-
操作路径错误
hugo构建命令必须在 项目根目录 执行。git push部署命令必须在 public 目录 内执行。
7.备份与还原流程
基于“源码”与“产物”分离的双仓库策略,我们的备份重心完全在于源码仓库 (Source Repo)。只要源码在,网站随时可以重生。以下是日常备份和更换电脑时的还原步骤。
1.源码日常备份
在写完文章并部署(git push -f 到了 GitHub Pages)之后,不要忘记将源码同步到你的私有仓库。
操作位置:项目根目录 ~/myblog
# 1. 确认不在 public 目录中
cd ~/myblog
# 2. 提交源码变更
git add .
git commit -m "Backup: add new post and update config"
# 3. 推送到私有源码仓库 (Source Repo)
git push origin main
注意:由于
.gitignore中已经忽略了/public目录,这里只会上传 Markdown、配置文件和主题设置,不会上传生成的 HTML 垃圾。
2.异地还原/迁移 (更换电脑/重装系统)
假设你在一台全新的 WSL 环境中,需要恢复写作环境,请严格按照以下步骤操作。
第一步:安装环境 重新按照本文第 2 节的方法,安装 Hugo Extended 版本。
第二步:克隆源码 (一步到位)
使用 --recursive 参数,在克隆源码仓库的同时,自动拉取 PaperMod 主题文件(子模块)。
# 核心命令:--recursive 会自动处理子模块
git clone --recursive https://github.com/yourname/myblog-source.git myblog
cd myblog
第三步:验证与恢复 此时,源码和主题都已就绪。你可以直接尝试运行本地预览:
hugo server -D
如果一切正常,即可开始新一轮的写作。下次发布时,Hugo 会自动重新创建 public 目录,你无需手动从旧电脑拷贝该文件夹。
3.常见问题处理
- 忘记加 –recursive 怎么办?
如果你手快直接用了
git clone,你会发现themes/PaperMod文件夹是空的,Hugo 会报错。此时在项目根目录补救执行以下命令即可:git submodule update --init --recursive - Public 目录冲突:如果在还原后发现
public目录里有奇怪的文件,直接rm -rf public删掉即可,Hugo 会负责重新生成。