折腾笔记:从 Misskey 到 Rhex,再到 Discourse,最后我放弃了……但我又回来了

最近手头有一台配置不算高的 VPS,2G 内存。想着既然闲置也是闲置,不如搭个属于自己的社交平台或者论坛。初衷很简单:能发帖、能互动、别太占资源。结果这一折腾,就是半个多月,中间几度想摔键盘。

故事是从 Misskey 开始的。那种类似微博的卡片式交互,还有联邦宇宙(Fediverse)的概念,看介绍特别心动。但现实很快给了我一闷棍。Misskey 是 Node.js 写的,大家都知道,Node 应用最怕的就是构建。我在服务器上跑 pnpm installnpm run build,看着日志刷了好几屏,然后进程就没了。查了一下,是被系统的 OOM Killer 干掉了——内存爆了。

我不信邪,开始给系统加 Swap。从 2G 加到 4G,甚至试过 8G。确实,Swap 加上后,构建能跑完了,但慢得像蜗牛。而且 Misskey 依赖 Redis 和 PostgreSQL,Docker 一启动,服务器 CPU 就开始疯狂报警。那一刻我觉得,为了一个玩具项目把服务器搞得这么累,不值当。

于是我转向了 Rhex。这是一个基于 Next.js 的论坛程序,看起来清爽现代。但噩梦换了个马甲又来了。Next.js 的 next build简直是内存吞噬兽。在我的 2G 机器上,它直接报 Bus error (core dumped)。我查遍了 GitHub Issue,降 Node 版本,关 Turbopack,我试了个遍。结果就是:数据库初始化成功了,但前端死活构建不出来。每次 Docker 重启,日志就在那里无限循环:“找不到 .next目录”。我知道,又是内存不够惹的祸。

既然 Node.js 这么重,我想起了传说中“重剑无锋”的 Discourse。它是 Ruby on Rails 写的,尽管也沉,但是运行前不用编译。1Panel 的应用商店里也有一键安装,我心想这下总该省心了吧?装是装上了,确实比 Node 系列稳,但它实在是太沉了。作为一个全栈式论坛,它自带 PostgreSQL、Redis、Sidekiq 等等一堆东西。我的小机器跑起来,CPU 常年 90% 以上。这种“为了跑软件而跑软件”的状态,让我觉得很空虚。

中间我还去翻了 Flarum,结果 PHP 的老毛病,依赖复杂,而且我总觉得它太老了,界面也不太符合我对“社交平台”的想象。我还动了自己用 ASP.NET 写一个的念头,理智告诉我那是另一个无底洞。

最后,我又头铁了一次,决定再给 Misskey 一次机会。我认真配置了 4G 的 Swap,改了 Redis 的内存限制,甚至换了国内镜像源。看着日志一点点滚动,我以为这次终于要成功了。结果还是卡在了某个我也不知道是什么的地方。

那一刻,我坐在电脑前,看着满屏幕的 docker compose logs,突然就不想折腾了。

我意识到,我并不是真的需要一个多么完美的社交平台,我只是想要一个能安安静静写字、偶尔有人回两句的地方。为了追求所谓的“功能强大”和“技术时髦”,我把自己困在了 Docker、Swap、OOM 和 Node 依赖的泥潭里。

所以,我决定放弃。

我 SSH 登录服务器,敲下了这几行命令:

# 删除 Misskey 目录
rm -rf /opt/misskey

# 关闭并删除 Swap
sudo swapoff /swap
sudo rm -f /swap
sudo sed -i '/\/swap/d' /etc/fstab

看着硬盘空间被释放,Swap 被卸载,服务器的负载瞬间降了下来,我的心也跟着静下来了。


峰回路转:遇见 bbs-go

就在我准备彻底躺平时,我鬼使神差地在 GitHub 上搜到了 bbs-go

看了一眼简介:

  • Go 语言编写(编译型,运行起来不吃内存)
  • 自带轻量级全文搜索(不用再折腾 ElasticSearch)
  • 支持 Docker 一键部署
  • 界面清爽,有论坛也有问答

关键是,它不像 Misskey 那样臃肿,也不像 Discourse 那样全家桶。它就是一个纯粹的、为小服务器设计的社区系统。

抱着“最后一次,不行就真的睡觉”的心态,我开始了新的尝试。

1. 准备环境

首先,清理战场。确保之前的 Docker 容器都删干净了。

docker system prune -af

然后,我没有像之前那样搞巨大的 Swap,这一次甚至没有加 Swap(毕竟 Go 程序跑起来根本用不到这么多)。

2. 编写 docker-compose.yml

bbs-go 的官方文档其实已经很友好了,但为了适配我的 1Panel 和 PostgreSQL,我稍微调整了一下配置。

这是我最终使用的 docker-compose.yml

version: '3.8'

services:
  bbs-go:
    image: mlogclub/bbs-go:latest
    container_name: bbs-go
    restart: unless-stopped
    ports:
      - "8080:8080" # 前端端口
      - "8090:8090" # 管理后台端口
    volumes:
      - ./data:/data # 持久化数据
    environment:
      # 数据库配置(使用 1Panel 的 PostgreSQL)
      BBSGO_DB_TYPE: postgres
      BBSGO_DB_HOST: postgresql # 1Panel 容器名
      BBSGO_DB_PORT: 5432
      BBSGO_DB_USER: bbsgo
      BBSGO_DB_PASSWORD: your_strong_password
      BBSGO_DB_NAME: bbsgo
  
      # 站点基础配置
      BBSGO_SITE_NAME: "我的小站"
      BBSGO_BASE_URL: "http://103.149.93.204:8080"
  
      # 关闭不必要的功能以减少资源占用
      BBSGO_ENABLE_SEARCH: false # 暂时关闭内置搜索,需要时再开
    networks:
      - 1panel-network

networks:
  1panel-network:
    external: true

3. 见证奇迹的时刻

/opt/bbs-go目录下,我深吸一口气,使用 1Panel 的 Go 运行时镜像运行:

docker compose up -d

然后,我盯着 docker logs bbs-go

没有疯狂刷屏的内存报错,没有卡死的构建过程,也没有 CPU 100% 的警报。大概过了十几秒,日志停了。

我颤抖着手指,在浏览器输入了地址:http://服务器IP:8082

页面加载出来了。

速度快得惊人。我试着注册了一个账号,发了第一篇帖子,编辑了个人资料。一切都顺滑得不像话。

我又打开了服务器监控,内存占用稳稳地停在 50****MB 左右,CPU 安静得像睡着了。


结语

这次经历教会了我一件事:合适比强大更重要,完成比完美更让人安心。

Node.js 的世界虽然绚丽,但对于小内存 VPS 来说,就像是让一辆 F1 赛车去乡间土路拉货。而 Go 语言编写的程序,就像是一辆皮实耐造的拖拉机,看着不花哨,但活儿是真能干。

从 Misskey 到 Rhex,再到 Discourse,我走了很多弯路。但最终找到 bbs-go,让我觉得这一切折腾都值了。

不再追求联邦宇宙的宏大叙事,也不再纠结于前端框架的时髦与否。一个能让我安静写字的角落,才是我真正需要的。

就这样吧,这次是真的收工了。

晚安,服务器。


(如果你也想试试 bbs-go,可以去它的 GitHub 主页看看,真的很适合“贫民窟”服务器。)

评论