自给自足
我购买了一台 VPS(的使用权)后,自托管了一些服务。放在一个领地的角度来看,想必便是可以自给自足的地方吧,就像种庄稼的农田。
该网站
首先,自然是你现在所在的这个网站了。因为是静态博客,部署上去的也只是数个静态文件。
这些静态文件们都开源,见 这里。
代码托管平台
之前我部署过 Sourcehut 实例,因为当时觉得它没有用 GitHub 那套 pull request 的代码协作模式、很酷。但是自建起来要吃的硬件资源不少,最后还是迁移走了。
现在挂在 git.cytrogen.icu 上的是 Forgejo。非常轻量非常快。
目前服务跑在家里的台式机上⸺具体是怎么做到的呢,之后你就知道啦⸺不开放账户注册,因为实在是没有精力去管理。
如果想要提补丁的话,随时欢迎发邮件给我。不过我的项目多数都是只给我自己用的 vibe 工具或者 Emacs 配置文件式的软件……
Gemini 胶囊
除了 Web,我还给博客做了个 Gemini 版本,用 agate 托管,地址是 gemini://cytrogen.icu。随便找个 Gemini 客户端就能读啦。
邮箱服务
通过 Stalwart Mail Server,构建和维护一个自己的邮件服务器变得非常简单。
需要提起的是,大多数 VPS 提供商都会关闭 25 端口。我专门打了电话给 IONOS,才将这个端口开放。要是提供商就是要关闭的话,可以考虑使用 SMTP2GO、Resend 这样的中继器。
本站的文章下方还接入了套邮件评论系统,模仿邮件列表的运作方式。邮件就是由 Stalwart 接收,通过 MTA Hook 交给个常驻进程解析,再由定时任务组装成嵌套的讨论树的。
别名管理
邮箱暴露在公网上,难免会被各种服务转卖、泄露。我给每个注册的服务都用专属的别名⸺比如 Amazon 就会用 amazon@。
一旦某个别名开始收到不相干的垃圾邮件,我就知道是谁把我的地址卖了出去。为此我写了 Alias Guard,可以管理别名的黑名单。
XMPP
我用 Prosody 搭了套 XMPP 服务,也注册了 cytrogen@xmpp.cytrogen.icu。
现实是…… 身边几乎没有人使用,哈哈……
Fediverse
我在 gts.cytrogen.icu 上跑了个 GoToSocial 实例,账号是 @cytrogen@gts.cytrogen.icu。
博客的部分文章会在发布时一起同步过去,读者朋友们可以在 Fediverse 上直接点赞、转发或者回复。
顺带地,我把每月的归档做了个静态站 gtsm.cytrogen.icu,以及 fork 了别人的 GoToSocial 客户端 masto-fe.cytrogen.icu。
推送通知
ntfy 是个极简的推送服务。我用它把服务器上的各种事件推送到手机。
RSS 聚合器
FreshRSS 是一个颇为知名的 RSS 聚合器兼阅读器,不过我的设备上都有自己的本地阅读器,所以它只用来抓取我的订阅源们啦。
用户需要我自行注册。如果有人想要使用这种服务的话,可以联系我。只是我还在考虑是否应该帮助他人托管 RSS 聚合服务……
服务器与容器监控平台
既然都有 VPS 了,怎么会没有监控服务呢?我选择的是 Beszel,相当轻便。除了可以看到硬件资源外,还可以看到每个 Docker 容器的状态以及日志。
家里跑的 hub 也可以看到具体的情况。
可用性监控
我给每个对外服务都配了 Uptime Kuma 的探针。一旦有谁挂了,或者证书快到期了,我都会被提醒到。
Telegram Bot
这并不是给我使用的服务…… 室友喜欢的 GPT 4 系列被 OpenAI 下架,只能使用 API 来访问 GPT 4o 或者 4.1。如果是电脑的话,还能访问 OpenAI 的沙盒。那移动端呢?最好是使用一个稍微正常点的客户端。在权衡之下,我们选择了 Telegram Bot。而我因为偷懒,用的是 pipedude 的 evi-run 项目,因为它提供了 Docker 镜像。
实际部署期间发现该项目还是存在着许多小问题,最主要的便是要在代码里硬编码 prompt,实在是不够优雅!遂改成读取 .txt 文件的方式获取 prompt。然后是语言上,作者只提供了英语和俄语,只能自己添加中文。
说到 Bot,我最初学习编程时,开始捣鼓的第二个项目便是 Bot。那会儿 QQ 抓第三方 Bot 还没有抓那么紧,我创建的那个 Bot 起初叫 Kami,后面改名为 Hoka。后面因为 CQHttp 的没落,我也就不再折腾 Bot…… 其实现在因为 QQNT 项目的出现,Bot 应该比过去更好创建了才是,或许我也可以重新拿起 Bot 开发。
不过现在只会偶尔运行该服务。室友已经习惯于 GPT 5 以及之后的 6 了。
Headscale
重量级!
要让 VPS 和家里的机器互相看见,又不把它们直接暴露到公网,我用了 Headscale。现在台式机、笔记本、手机、VPS 都接在同个虚拟内网中,用起来超级方便!
有了它,家里跑的服务就不用占用公网的端口,也不用经过任何第三方了。
这些是我不对外网开放的服务:
- Immich:备份照片与视频
- Jellyfin:影视库,可以拿来看电影还有剧集
- Navidrome:音乐流媒体服务
- Paperless-ngx:纸质文档的归宿…… 目前还在学习怎么用
- Dawarich:记录自己的位置历史,类似于 Google Timeline 吧
- MeTube:网页版的 yt-dlp
- LibreTV:轻量电视
- RSSHub:给不提供 RSS 的网站现造个 RSS
门禁
对于一些不对外开放的服务或者面板,我用 Authelia 给它们加了层登录认证。
Webmention
本站已接入 Webmention。
接收端用的是 Eltrac 的 Weepinbell。因为原先的 webmention.io 经常挂,并且源代码被原作者用 AI 工具重新乱写一通让我觉得很诡异、不可靠,所以换掉了。如果有人懂 Clojure 的话,可以贡献点代码喔。万分感谢。
另外一个麻烦家伙儿是 brid.gy。它处理 Fediverse 互动的逻辑很奇怪,所以为什么不直接自己写个服务呢?反正只需要读 GoToSocial 收到的通知、转换成 Webmention 发到 Weepinbell 即可啊。
所以我额外写了个服务,负责反向把 GoToSocial 上的点赞、转发和回复桥接成 Webmention。
BentoPDF
pdf.cytrogen.icu 上跑着 BentoPDF,是个 PDF 工具箱,非常好用,还只用在浏览器里本地完成任务。