我的博客系统演变之路

TL;DR,目前用到的工具和服务

第一代

最开始(10年前)博客托管在 Github,使用 Jekyll 作为博客引擎,使用 disqus 作为评论系统,都是 Free to Use,可以很快地上线,网友们也可以方便地互动。

但免费的产品总有它的局限性,比如访问比较慢,也不能换博客引擎,Disqus 的隐私和大量请求带来的体验问题也日渐暴露。于是就开始寻找替代品。

第二代

先从博客引擎出发,因为当时 Go 看得比较多,很自然就找到了 Hugo,Disqus 的替代品最终锁定到了 giscus:一个基于 Github Discussion 的评论系统。内容则交给 Vercel 来托管。

如此又运行了一段时间,还算比较顺畅,但也遇到了些问题:

  • Hugo 给我的感觉是功能偏多,显得臃肿,模版语言也有点奇怪。
  • giscus 还是会发很多请求,作为一个评论系统不太能接受。
  • Vercel 免费版流量超限(费了一阵功夫排查,发现是 RSS 文件导致的),也欠缺些灵活度。

带着这些问题,继续改进这个系统。

第三代(目前这套系统)

第三代的关键字概括如下:尽量简单,足够灵活,独立部署,数据收敛。带着这几个目标,开始探索相关的工具。

静态内容引擎

出于对 Single Binary 的钟爱,以及正好有一段时间在学习 Rust,有被这门语言优雅到,于是就开始看有没有用 Rust 写的 SSG,然后就发现了 Zola:存活了 5 年,且还在持续维护,Issue 的 Open/Close 比在 1/5 左右(我的临界点是 1/3,越小越好),Star 数也还不错。翻了下文档,比 Hugo 简洁不少,核心的功能也都有提供,翻了下项目源码,分层清晰,代码质量也 OK。新的博客引擎就它了。

非文本内容

除了写文章,也想更新一些非文本类型的内容,比如照片,或者在看的电影。有两种做法,一个是使用 Zola 的自定义模版,然后内容也通过博客系统来更新,但这样会带来几个问题:

  • 每次更新照片,都要在本地打开项目,按照格式添加内容再提交,不太方便。
  • 如果表现形式稍微复杂些,可能会突破 Zola 的能力圈。
  • 一些大文件(比如视频片段)不太适合通过 Git 来管理。

另一个就是将动态内容托管出去,页面只负责搭框架,然后通过 fetch 去远端取内容再展示,这就需要一套 CMS,但市面上的 CMS 往往功能都很复杂,我其实只需要一个简单的管理后台,可以动态添加 Table 和 Column,然后有 REST API 可以供前端使用就行了。这样如果要创建一个新的服务(比如 Music),只要在后台新建一个 Table 和相关的 Column(如 Singer, Album, Duration 等等),然后添加相关的内容就行了。而 PocketBase 完美符合需求,而且还是 Single Binary。

PocketBase 的 Slogan 是:Open Source backend for your next SaaS and Mobile app in 1 file。只有一个二进制文件和一个数据目录,用户产生的内容(包括文件)都会在这个目录中,所以备份起来也很方便。

因为还要写一些 CSS 和 JS,所以用上了两个利器:TailwindCSSAlpineJS,确实挺升了不少开发效率。

动态内容

有了 PocketBase,实现评论系统就比较方便了,但因为会涉及到一些业务逻辑(校验内容,权限验证等),所以需要一个后端服务,从尽量简单,足够灵活这两点出发,选择了 Deno: std 能满足日常的需求,extension 虽然没有 node 的丰富,但也基本够用了,还有很重要的一点是没有 node_modules

因为平时开发一些页面会用到 TailwindCSS,所以给 package.json 加了些内容:

"scripts": {
  "dev-css": "tailwindcss -i ./styles/style.css -o ./static/assets/main.css --watch",
  "dev-zola": "zola serve --drafts -i 0.0.0.0 -o .cache",
  "dev": "concurrently 'npm:dev-css' 'npm:dev-zola'",
  "build-css": "tailwindcss -i ./styles/style.css -o ./static/assets/main.css --minify",
  "build-zola": "zola build",
  "build": "npm run build-css && npm run build-zola",
  "serv": "deno run -A serv/serv.ts"
}

网站托管和加速

Vercel 虽然很方便,也有边缘节点加速,但灵活度上还是差了些(比如要实现一些定时任务,或者与本地文件系统交互等),因此还是决定使用古老的 VPS,没有选择 AWS 或 Google Cloud 这类云服务主要考虑两点:1. 过于庞杂,看着就晕。2. 我喜欢每月固定费用,不用担心某天被攻击或其他意外情况导致费用飙升(或许可以跟客服沟通,但也很麻烦)。VPS 里我用过的觉得还不错的就 LinodeVultr,后者体验上更 Morden,而且支持支付宝,所以就选了它。

因为 VPS 固定在某个 Region,所以不同的地方访问速度上会有较大差异,这时就该 Cloudflare 上场了,它可以自动对静态文件进行全球加速(需要将域名通过 cloudflare 来管理,并且启用 auto proxy),而且不限流量,真是美滋滋。

Workflow

这套系统使用起来就像这样:足够简单,又有一定的灵活性,且数据都在自己的服务器上。

目前对这套架构还比较满意,应该能撑得久一些。

❤️