我的博客系统演变之路

Update: 最新版见这里

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,所以用上了两个利器:TailwindCSS 和 AlpineJS,确实挺升了不少开发效率。

动态内容

有了 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 里我用过的觉得还不错的就 Linode 和 Vultr,后者体验上更 Morden,而且支持支付宝,所以就选了它。

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

Workflow

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

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

Related Posts

何生水

何生水

cloudflare在国内访问的话,有些地方且有些时候会访问速度缓慢。你有自选IP,或者怎么解决吗?

limboy

limboy

@何生水 国内网络的话,我想要的是打开没问题,访问速度上尽量优化,但不会针对国内特定节点去优化。比如 VPS 如果国内效果确实不好,而 Vercel 可以优化这一点,或许会考虑切换,但如果上了 Vercel 但有些地方访问依旧缓慢,那也就这样吧。

李滨

李滨

您好主人:正想搭建个超简单的“官网”,搜索到了Jekyll,请问您感觉现在的它还值得推荐吗?类似的框架搜索出来好多,比如VuePress等。同时这个“官网”其实只要能访问、能够通过备案即可。但另一方面,也想进一步(下一步)实现一个CMS,像您这个博客一样,简洁,充实;只是要实现这种需求,需要怎样的技术栈呢?学习曲线怎样呢? 多谢。

limboy

limboy

@李滨 那其实选择还挺多的,选型的时候为将来的需求留点 buffer 就行。我的话还是会使用目前的这套,如果会 react 的话,next 也是不错的选择。jekyll 有段时间没有关注了。

李滨

李滨

@limboy 多谢指点。方便交换微信或者邮件吗? 有事相求 : ) 我的微信是 Leo_Been

Reorx

Reorx

用 PocketBase 来做书影音记录真是个好点子!之前只想到用它可以来做博客,但既然有静态生成器就没意义了。另外我也很喜欢 Zola,Jinja2 的模板语法是最好的,相比而言 Hugo 的 go template 真的非常痛苦。

李滨

李滨

来到这里才知道原来有这么多框架/脚手架,于是乎就更有些"不安"了——路漫漫其修远兮啊;还需要N多时间来种草/耕耘啊! 楼主及Reorx等前辈大牛能不能整理份最基本的知识清单啊,偶也好集中精力、各个击破 : ) 非常感谢啦。

rantrsim

rantrsim

您好~我是腾讯云开发者社区运营,关注了您分享的技术文章,觉得内容很棒,我们诚挚邀请您加入腾讯云自媒体分享计划。完整福利和申请地址请见:https://cloud.tencent.com/developer/support-plan 作者申请此计划后将作者的文章进行搬迁同步到社区的专栏下,你只需要简单填写一下表单申请即可,我们会给作者提供包括流量、云服务器等,另外还有些周边礼物。

ttys3

ttys3

zola 我确实也折腾过. 不过它有一些设定很不方便. 最典型的是, 子目录下的md文件它不给你索引(虽然后面至少折腾了半小时以上才解决, 需要在每个子目录下增加一个配置文件).而这些在hugo下面完成不会有问题. 很明显, 我打算用它也是基于钟爱 Rust. 但是目前我还是回退到了 hugo.

评论的话我不会选择自己造轮子. 有一些开源的非常优秀, 比如 umputun/remark42 (golang) 还有 posativ/isso (python), 或 serverless 的 giscus/giscus. 但是千万不要用 Valine.js 这种泄露用户隐私的东西.

limboy

limboy

@ttys3 子目录(Section)的问题,文档里有说,加了 _index.md 才会被认为是一个 Section,不然就只会生成静态页面(Orphan Pages)。

评论这块,我想要的是类似 Wordpress 那样不需要登录账号,又足够轻便的服务,没有找到太合适的就自己做了一个。

Kaspa

Kaspa

我最开始用Wordpress ,后来Jekyll 再后来hexo和hugo,最后又回到原点