如何利用全 SaaS 阵容从零免费搭建一个博客?

2024-08-23

即便已经几乎无人再会把”自搭自写“博客的 Programmer 称为 Geek,但我相信拥有一个 Self-Hosted Blog 依然是众多 Programmer 的普遍追求。虽然 GitHub Pages 和 Jekyll 的组合放到现在也依然不算过时,也不失简便,但考虑到如今各类 SaaS 服务层出不穷,那么在 2024 年的今天,我们能否利用全 SaaS 阵容从零免费搭建一个博客?

rsomhaP 作为博客程序

关注过我博客的朋友可能会知道在过去的十余载里,Pomash 是我自己拿 Python 写成,也是我自己一直在用的博客程序。不过在使用和维护的过程中我也逐渐发现这个几乎写成于十年前的博客程序似乎有点”过时“了,整理过后,我为造轮子另起炉灶罗列了几点冠冕堂皇的理由:

  • Python 已经不再是我熟悉的语言,诸多语言特性和最佳实践我已经不甚了解。
  • 虽然 Pomash 是个很简单的博客引擎,但从代码中也不难看出我曾经”笔法“的稚嫩——有很多不忍直视的代码。
  • 用一个 SQLite 文件存储我数十年以来的博客文章听起来一点也不高可用。
  • 用 Rust 重写 XXX 是流量密码。

于是乎作为一次具有某种”致敬“意味的行为艺术,我用 Rust 重写了 Pomash,并用我很喜欢的命名法给它起了一个新名字:

'r{}'.format(''.join(sorted('Pomash'))[::-1]) == 'rsomhaP'

somhaP 是 Pomash 重排后的字符串,加一个字母 r 在开头拼接成 rs 意指用 Rust 重写而成——rsomhaP

为了全面拥抱 SaaS 服务简化实现与部署,在造轮子的同时“反造轮子”,我在重写的时候带着这么几个原则:

  • 依然是 Markdown 友好。
  • 保持单体程序,拒绝前后端分离(其实是我不会写前端)。
  • 简洁且易读的样式。
  • 尽可能使用 SaaS 友好的方式去设计部署方式。

所以最后,这篇文章也孕育而生,让我们看看要跑起来一个 rsomhaP 的博客程序,我们需要哪些步骤。

TiDB Serverless 作为数据库

rsomhaP 抛弃了 SQLite 作为本地数据存储,直接使用现在几乎烂大街的 DB SaaS,目前还只支持 MySQL-compatible 的数据库服务,后续也许会考虑支持 PostgreSQL。

这里我自然选择了利益相关的 TiDB Serverless 作为后端数据库 SaaS,注册并创建好集群,拿到数据库的 Host 等参数即可,没有任何额外的步骤。

免费额度的集群规格对我们来说绰绰有余

MySQL 相关的配置直接写到 rsomhaP 的配置文件里或用环境变量 MYSQL_CONNECTION_URL 均可。

[mysql]
# If `connection_url` is set, other connection-related configs will be ignored.
# connection_url = "mysql://root:password@127.0.0.1:4000/rsomhaP"
username = "root"
password = "password"
host = "127.0.0.1"
port = 4000
database = "rsomhaP"

唯一需要注意的点是这里需要提前创建好一个 database:

CREATE DATABASE rsomhaP;

除了天然的享受到了 TiDB 作为一个分布式数据库的优势,我们也可以在 TiDB Cloud 的面板上自动设置自己数据库的备份时间与频率,为自己智慧的结晶多上一份保险。

Fly.io 作为部署机器

数据库有了,那么我们至少需要一个 Host 或者说机器来实际部署运行我们的 rsomhaP 程序,除了直接去 Vultr 这类地方买虚拟云主机,我们还有一个更“小而美”的选择:Fly.io

其实我曾经也写过一篇关于它的博客:Fly.io 初体验之博客搬家。彼时我把 Pomash 迁移了上去,整个体验也非常的丝滑,所以在这里依旧沿用了之前的选择。

我为 rsomhaP 直接写好了一份可以用于 Fly.io 部署的 Dockerfilefly.toml,所以你需要做的仅仅是安装好 flyctl,按自己的配置改好 config.toml 然后在 rsomhaP 的目录下运行:

fly deploy --config fly.toml

这里如果你是第一次用 Fly.io,那么直接运行可能会提示你没有 rsomhap 这个 App。你可以选择去 Fly.io 的网页端 Dashboard 手动创建,也可以直接在命令行里创建:

fly apps create rsomhap

紧接着一路按照提示进行配置即可,这里有两个地方需要注意一下。

首先是为了保证和数据库服务的连通性,我在部署时选择了和 TiDB Serverless 集群位于相同地区的日本 Region,可以在 fly.toml 里这样配置:

app = "rsomhap"
primary_region = "nrt"

对于全部的可用 Region,可以参考这篇官方文档

部署完成后便可以通过形如 https://app-name.fly.dev 的 Hostname 来访问你刚刚部署好的 rsomhaP 了,Fly.io 当然也支持接入自定义域名和配置免费的 SSL 证书,均可通过网页 Dashboard 或 flyctl 做到,参考

Cloudflare R2 作为图床

恭喜你,上面哪些步骤全部完成后,你就已经拥有一个可以访问和写作的博客了🎉

但要想进行图文写作,我们还差这最后一步“图”,由于 rsomhaP 本身并不支持上传和存储图片,所以拥有一个稳定的图床服务是有必要的,这里我们可以用赛博大基建 Cloudflare R2 的对象存储作为我们的图床设施,具体设置方法可以参考这篇文章,写得很好很详细,我就不再次展开了:从零开始搭建你的免费图床系统(Cloudflare R2 + WebP Cloud + PicGo)

WebP Cloud Services 作为图床代理

有了图床的“床”,我们还可以更精进一步,用 WebP Cloud Services 这个图片代理 SaaS 来实现更多的功能:

  • 不改变画质的情况下进行图片体积压缩,并作为图床缓存,加快博客的加载速度。
  • 隐私擦除,添加水印等自动的图片二次处理。
  • 自定义 Header 来实现更安全的图床访问。

同样推荐大家参考上面那篇文章的作者:

结语

至此,使用 rsomhaP 搭配一众免费 SaaS 的博客部署就完成了,你可以继续浏览本站或者去 rsomhaP 的 GitHub 界面了解更多信息,其实关于 rsomhaP 的开发过程也有很多可以分享的点——例如 axum 库的使用,Markdown 渲染的实现等,待我挖个坑日后再填。