Hugo

下线 WordPress,躲过 PHP 漏洞,瘦身 Hugo 输出

八月底把博客迁移到 Hugo,九月初又把历史文章都按 Markdown 整理了一遍,之后正常写了几篇新文章。按迁移时的规划,把旧 WordPress 留在 VPS 上空跑一段时间,以备还有啥需要迁移的

这几天趁着 Tibo 不停重置 Codex 的使用额度,再让 AI 验证迁移确实没有遗漏,把旧系统下线并卸载依赖,顺便把之前模板在每个页面里完整输出的侧边栏做了下优化瘦身

下线旧 WordPress

从八月底切换到 Hugo 开始,访问就已经全部走 Hugo 生成的静态文件,nginx 配置里也没有再把请求转发给 PHP

这次让 AI 先帮忙核查了一遍,确认现在的文章、图片、RSS、搜索和评论标识都不需要 WordPress,旧站里的图片也都已经在新站找到对应文件,已有的文件和数据库备份继续保留,才开始动手

10 月 20 日先停掉 MySQL 和 PHP-FPM,释放空跑占用的 VPS 内存,禁用开机启动,顺带把之前人肉维护的每日备份到 Dropbox 和 Google Drive 的脚本也停了。同时让 AI 修了一个 RSS 的小问题,原来 /blog/feed/ 可以正常访问,但少了最后那个斜杠的 /blog/feed 会返回 404,现在加了跳转

停掉后又观察了一天,确认正常访问没受影响,21 日把 PHP、MySQL 相关的软件包卸载,再清掉旧 WordPress 目录和数据库文件,也省得每次 apt upgrade 还要更新一堆没用的包

非常巧,PHP 官方在 10 月 21 日发布紧急安全更新,修复两个可能导致未认证远程代码执行的严重漏洞(CVE-2026-109618 和 CVE-2026-109619)。我这边下午刚把 PHP 卸载完,当天就赶上了紧急补丁发布。八月底公开访问就已经不经过 PHP,这次连运行环境也收掉了,刚好省了追着看影响范围和打补丁的事,庆幸有时候抠门省事也能少操一点心

这也符合之前迁移到 Hugo 的目标之一,减少对 WordPress、PHP 等的依赖,只放静态文件在 VPS 上,未来再要迁移也容易很多

同步 whusnoopy.github.io

GitHub 很早就有这个用自己用户名开头、以 github.io 结尾的 GitHub Pages 托管服务,早先打算折腾 Hugo,也是从考虑 GitHub Pages 默认支持的 Jekyll 看起,后面发现还是用 Hugo 更符合自己的需求

这次顺带让 Codex 完成了对 whusnoopy.github.io 的镜像流程,未来如果懒得自己维护 VPS 了,再配好自定义域名和 DNS,把它改成主站应该也可以的

瘦身 Hugo 输出

往 github.io 做镜像同步时,发现 Hugo 的输出目录到了 600 MiB+,这个空间占用明显超出预期,原来的 WordPress 站点目录在清理前核查时约 264 MiB。Codex 在分析能否将 github.io 做镜像时还提到,GitHub Pages 已发布站点的大小不能超过 1 GB,这一下就用掉了大半

自己人肉简单看了下是不是附件图片什么的太大了,用 gdu 扫了下也还好,就是旧文章里的图片链接还在 wp-content/uploads,新文章的图片放在 media/posts 下。这些旧地址继续保留,毕竟二十多年的各种历史包袱,能不动就不动,省得哪天又冒出来一个旧链接打不开

继续看,是最终生成的各种 HTML 文件累积起来太大了,一开始还怀疑是 Tag 和分类太多,导致输出的文件数量过多,后来让 AI 一查,是每个页面重复输出了完整侧边栏导致的

迁移到 Hugo 时为了保留原来的使用习惯,把右侧按年、月展开的文章归档也搬了过来。这东西在 WordPress 时代用的是 Collapsing Archives,之前还为兼容 PHP 8 修过插件,自己用习惯了这一套,希望能继续按年月翻旧文章

不过之前本站的模板实现就是把二十多年的年月、八百多篇文章的标题和链接,以及折叠用的按钮、列表结构,全部生成到每一个页面里,哪怕后来加了默认收起来等 JS 行为,实际上每页光侧边栏就有大约 216 KiB 的 HTML

算上文章分类、标签、年月归档和各种分页,整站的两千多个页面,把这部分内容原封不动输出了两千多遍。难怪文章和图片都没怎么变化,生成出来的整站文件却有 600 MiB+

找到问题就改呗,现在虽然不用 WordPress 动态输出,但可以把侧边栏依赖的文章归档数据提取到一个共用的 archive-index.json,页面里只留容器,由浏览器读取数据来生成年月列表,展开某个月时再创建里面的文章链接。这样同一份数据不用在每个 HTML 里塞一份,也可以利用浏览器缓存,跨页面访问时不必每次都重新传输整份数据,原来按年月展开、记住展开状态的功能都还在

这一波整完,单页侧边栏从 216 KiB 降到 8.3 KiB,整站从 632 MiB 降到 141 MiB

后面继续把文章分类和常用标签也用类似的方式处理,两块共用一份 sidebar-index.json,再把分页模板输出里那些没必要的缩进和换行裁掉。最后结果是

构建状态 单页侧边栏大小 整站文件大小
优化前 约 216 KiB 约 632 MiB
年月归档改用共享 JSON 约 8.3 KiB 约 141 MiB
分类、标签及分页继续优化 约 1.9 KiB 约 125 MiB

后面的优化收益没那么大,不过现在整个输出约 125 MiB,已经比之前含 WP 系统的旧站目录小了,每次发布和同步 github.io 镜像需要处理的数据也少了很多,离 GitHub Pages 的容量上限也还远,满意

随记

八月底迁移时想着后面就安心写东西吧,结果这两个月又断断续续折腾了不少。现在旧系统退役,生成文件也瘦了一大圈,希望接下来能多写几篇文章,少折腾点博客本身吧

现在我也变成用 AI 来输出内容的懒人了,上面引用这部分是 AI 输出的原文,更前面的内容是让 AI 用我的文风出的草稿,我改了一遍后的结果。有好有坏吧,先保持自己的想法记录输出,再继续平衡内容中的机械味和活人感

将博客迁移到用 Hugo 驱动

过去这些年一直用 WordPress 做博客的后端,其实也没什么不好的,任何一个浏览器打开就能写和管理,虽然后端重了点,但一次配置好也不用怎么折腾,现在的 VPS 跑个 PHP 和 MySQL 还是够的

前两年考虑要不要彻底使用 Markdown 来做内容管理,同时把整站变成不用那么多依赖的情况,比如挂 GitHub Pages 上用 Jekyll 直接生成。后面找了下发现 Hugo 这个基于 go-lang 的本地生成服务,当时还尝试看看要不要迁移,不过文档写得总是容易,对我这个历经二十多年,里面糅合了好多历史平台的内容,跑完第一步后就懒得将其往前推进到一个明确可用状态

今年各种 AI 能力突飞猛进到真的可以干活了,于是找 Codex,在 GPT 5.6 Sol 的帮助下,先确认是可以迁移的,需要备份保留哪些数据,怎么转移和验证,并逐步算完成了迁移和整理吧

既有数据迁移倒是还快的,毕竟想要啥我都能给出来,不管是 WordPress 所在目录和之前各种静态文件所在的 wp-content,还是 MySQL 数据库表,或者是 WordPress 导出的 wxr,还包括用作评论的 Disqus 的所有导出数据

接下来的验证整合,确实验证了各种历史沉淀,光是博文,就从最早的教育网博客,到 Live Space、百度空间、QQ 空间、人人网、Blogspot、自建 WordPress 等等

评论早年很多平台的应该都被丢失了,最早接的第三方评论系统应该是多说,这个没了后应该一直用的 Disqus,在整理过程中还把 Disqus 历史迁移没匹配上的好些内容也给匹配上了,AI 真强大

再就是把历史的外链图片都想办法补到本地,包括之前用新浪微博当图床的,还好现在微博还在把相册下载到本地能匹配上,还有用人人当图床的,从我几年前备份的人人网数据里匹配到一些,但也有之前备份就有遗漏的找不到,还好从我自己的照片库,再把当年发文时配的原图人肉找到,在 Live Space 阶段的图,通过 OneDrive 的日志图片找到绝大部分,很诡异的有一张图不在这个目录,还好通过 OneDrive 按日期的照片墙,最终也找到了那张,在 Google Photo 的图现在还能访问,AI 就直接帮忙下载备份到本地了,有两张曾经传在教育网博客的无关紧要的示意图,找不到就算了,还有之前用 163 相册的图,就从自己的照片库里去匹配上,最终还有曾经在水木的一张图也不可能找到,就算了吧

在样式比对时,修复了部分代码块和引用块的问题,同时还发现历史一些应该是通过 Live Writer 发的旧文,是一个单行超大的 HTML 语法,曾经在 WordPress 上转 Markdown 应该也是转到懒得转,这次先把和引用块的临时处理下,后面应该可以借助 AI 的能力可以快速批量处理

不过,加上本地搜索功能后,开发环境需要的依赖还是不少的,从 AI 帮项目生成维护的 README 里就能看到

必须工具

  • Git;
  • GNU Make 或兼容的 make;
  • Python 3.11 或更高版本;脚本只使用标准库,不需要 pip/virtualenv;
  • Node.js 20 或更高版本及 npm;只用于按 package-lock.json 安装和运行 Pagefind;
  • Hugo Extended;当前验收版本为 0.165.0,建议其他机器使用相同版本,至少必须在
    hugo version 输出中包含 extended;
  • 部署机器还需要 OpenSSH client,以及包含安全更新并支持 --link-dest 的 rsync。

可选工具:Docker 或本机 nginx,用于正式切换前的 nginx 配置和 HTTP 冒烟测试。

git 作为版本管理没有什么好解释的,AI 用 make 来串起各种动作,拿 python 运行各种转换和校验脚本,node 是为了安装运行本地搜索支持工具 Pagefind,hugo 是本次核心迁移组件,另外用 ssh 和 rsync 是为了推送发布到 VPS

大头基本完成,后面应该就是把单页目录样式小组件做下样式和功能优化,把整站的主题做做美化,再把历史文章都想办法转成 Markdown 格式,就安心写东西吧