SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

小型VPS自托管RSS阅读器对比:Miniflux与FreshRSS

比较 Miniflux、FreshRSS、CommaFeed、yarr 和 Tiny Tiny RSS 的内存预算、数据库要求、Fever 与 Google Reader API 支持,以及升级方式,帮助您选择适合小型 VPS 的阅读器。

小型 VPS 适合使用哪款自托管 RSS 阅读器

Miniflux 是适合部署在小型 VPS 上的自托管 RSS 阅读器。它是一个 Go 二进制文件,与 PostgreSQL 配合运行。它支持 Fever 和 Google Reader API,因此第三方手机应用可以连接;升级只需执行一个 docker compose pull。如果您需要扩展,以及一个内置 SQLite 的容器,请改用 FreshRSS。

有 5 款阅读器值得占用 VPS 的磁盘空间:Miniflux、FreshRSS、CommaFeed、yarr 和 Tiny Tiny RSS。本页比较它们实际存在的差异:每个软件栈所需的内存、各自要求使用的数据库、手机应用所需的同步 API,以及升级时会发生什么。本文中的每个数据要么由项目公开,要么是简单计算得出,并会明确说明来源。这些数据都不是针对您硬件的基准测试,因此请使用 docker stats 测量您自己的服务器。

五位读者,每位一段

Miniflux 使用 Go 编写,以单个静态编译二进制文件发布。其文档明确指出唯一的硬性依赖:“只能使用 PostgreSQL”。它不支持 SQLite 模式。它提供 REST API、Fever 兼容 API 和 Google Reader 兼容 API,还支持 OPML 导入和导出。全文搜索由 PostgreSQL 负责,这也是数据库不可选的原因之一。

FreshRSS 使用 PHP 编写,以一个同时包含 Web 服务器和应用的容器运行。SQLite 是默认数据库,不需要额外服务;较大规模的部署也支持 PostgreSQL 和 MySQL。它支持 Google Reader API 和 Fever API。安装步骤已在我们的 VPS 上部署 FreshRSS 教程中介绍,因此本页只进行比较,不重复安装过程。

CommaFeed 使用基于 Quarkus 的 Java 编写,其布局仿照 Google Reader。它在构建时而不是运行时选择数据库,因此项目会针对每种数据库发布一个镜像:athou/commafeed:latest-h2 对应嵌入式 H2 数据库,athou/commafeed:latest-postgresql 对应 PostgreSQL,另有适用于 MySQL 和 MariaDB 的变体。这些标签对应原生编译构建,带有 -jvm 后缀的变体则表示在 JVM 上运行。它提供 REST API 和 Fever 兼容 API;从 7.3.0 版本(2026 年 8 月)开始,也提供 Google Reader 兼容 API。

yarr(yet another rss reader)是一个内置 SQLite 的 Go 二进制文件,完全不需要容器。普通的 ./yarr 会监听 127.0.0.1:7070。它的选项很简短:-addr 0.0.0.0:7070 -auth alice:secret 可在密码保护下允许网络访问,-db /data/yarr.db 可将数据库放置在指定位置。它提供 Fever 兼容 API。其最新标签版本是 2026 年 9 月发布的 v2.9,并于 2026 年 10 月检查;此前 v2.7 于 6 月发布,v2.8 于 7 月发布,因此项目目前又在积极开发。

Tiny Tiny RSS 是五者中历史最久、运行负担也最重的项目。tt-rss.org 上的原始项目已于 2025 年 11 月 1 日退役,开发工作在社区分支 github.com/tt-rss/tt-rss 中继续,该分支的文档现已作为官方安装文档。该部署由四项服务组成:PostgreSQL 容器、PHP-FPM 应用容器、用于获取订阅源的独立更新容器,以及前置的 nginx 容器。文档明确说明:“此部署使用 PostgreSQL”。它提供自己的 JSON API,Android 客户端和多个第三方应用都使用该 API。不支持 Fever。

每个堆栈需要多少内存

下面的数值是预算,不是测量结果:它们表示每个堆栈在小型 VPS 上应保持低于的内存上限。CommaFeed 的数值来自项目公开发布的示例,该示例将容器限制为 256 MB。其他数值是为 feed fetcher 留出余量后的上限,因为刷新周期开始时,通常是它产生内存峰值。

图表Memory ceiling per reader stack, in MB
此图表背后的数据
[
  {
    "label": "yarr (SQLite)",
    "containers": 1,
    "mem_limit_mb": 128
  },
  {
    "label": "FreshRSS (SQLite)",
    "containers": 1,
    "mem_limit_mb": 256
  },
  {
    "label": "CommaFeed (H2)",
    "containers": 1,
    "mem_limit_mb": 256
  },
  {
    "label": "Miniflux + Postgres",
    "containers": 2,
    "mem_limit_mb": 320
  },
  {
    "label": "Tiny Tiny RSS",
    "containers": 4,
    "mem_limit_mb": 640
  }
]

yarr 的内存占用最低,为 128 MB,因为它只有一个二进制文件和一个 SQLite 文件,不需要数据库服务器或语言运行时。Miniflux 在 2 个容器中需要 320 MB,其中大部分内存由 PostgreSQL 使用,而不是由 Miniflux 使用。Tiny Tiny RSS 则是例外,在 4 个容器中需要 640 MB,因为应用、更新程序、数据库和 Web 服务器是4个独立进程,各自拥有独立的堆。

请将这些数值设置为实际限制,而不是仅凭预期。Docker Compose 中的内存限制介绍了相关语法,以及容器达到上限时的行为。未设置限制的容器不会在主机内存耗尽时优雅失败:内核会选择一个进程并将其终止,而且被终止的进程通常不是导致内存压力的容器。

每位读者都会迫使您选择的数据库

数据库是这 5 个阅读器之间最大的运维差异。它比用户界面的任何差异都更重要,因为数据库决定备份流程和升级风险。

Miniflux 和官方 Tiny Tiny RSS 安装都要求使用 PostgreSQL。它支持真正的全文搜索和安全的并发写入。但您需要额外运行一个容器、使用一个卷,还要处理一个周期性问题:官方 PostgreSQL 镜像无法原地迁移不同主版本之间的数据。Tiny Tiny RSS 文档对此有明确说明,并警告“官方 PostgreSQL 容器不支持在主版本之间迁移数据”。对于订阅源阅读器,现实可行的选择是固定使用旧主版本,或者使用 pg_dump 和 pg_restore 执行转储和恢复。PostgreSQL 还记录了 pg_upgrade 和基于复制的升级方式。对于停机时间很重要的大型数据库,这些方式增加的配置工作是值得的;而订阅源阅读器的数据库通常不属于这种情况。请按每 1 到 2 年执行一次此类升级来规划。

SQLite 是 FreshRSS 和 yarr 的默认数据库。它只有一个文件,不需要服务器、端口或密码。对于只有一个用户且订阅数为几百的场景,SQLite 的性能足够稳定;当多个用户同时写入时,性能会下降。这时 FreshRSS 的 PostgreSQL 选项就开始体现价值。yarr 在 v2.7 中增加了可选的 PostgreSQL 支持,但嵌入式文件仍是其常规运行方式。

H2 是 CommaFeed 的默认嵌入式数据库。在开始部署前,您应先考虑这一点,因为 CommaFeed 会在构建镜像时选择数据库。之后从 H2 切换到 PostgreSQL 不是修改配置即可完成的操作。您需要使用不同的镜像,并自行执行数据迁移。因此,请在服务器中积累一年的阅读历史之前做出决定。

手机应用能否正常使用

这个问题比很多人预想的更重要,因为 Web 界面只是使用订阅源阅读器的一半方式。

Miniflux 提供兼容 Fever 的 API 和兼容 Google Reader 的 API,因此大多数 iOS 和 Android 客户端都可以连接。FreshRSS 也提供这两种 API,并在其文档中说明了优先级:Google Reader API 的功能支持最完整,属于“最佳”选项;Fever API 则“功能有限,效率较低”。FreshRSS 还需要完成两个步骤,应用才能登录。首先,在 Authentication 下启用“Allow API access (required for mobile apps)”,然后在用户配置文件中创建 API 密码。如果跳过 API 密码,应用会出现身份验证失败,但 Web 登录仍然正常。在了解设置位置之前,这种现象很容易造成困惑。

CommaFeed 现在也同时提供这两种 API:它长期支持兼容 Fever 的 API,7.3.0 版本又增加了兼容 Google Reader 的 API,供不支持 Fever 的应用使用。因此,如果应用只支持 Google Reader,请运行 7.3.0 或更高版本。yarr 仅提供兼容 Fever 的 API,不提供其他 API,因此可以与支持 Fever 的客户端配合使用,但不能与只支持 Google Reader 的应用配合使用。Tiny Tiny RSS 则使用自有 API,因此需要使用专为它编写的客户端。在导入 300 个订阅源之前,请确认你选择的应用支持对应的阅读器。

1 GB 服务器上可正常运行的 Compose 文件

这是 Miniflux 服务栈,参考项目截至 2026 年 10 月提供的 Docker 示例进行了调整。发布的端口绑定到 loopback,监听地址已明确设置,两个容器也都设置了内存限制。

services:
  miniflux:
    image: miniflux/miniflux:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    depends_on:
      db:
        condition: service_healthy
    environment:
      - DATABASE_URL=postgres://miniflux:CHANGE_ME@db/miniflux?sslmode=disable
      - LISTEN_ADDR=0.0.0.0:8080
      - BASE_URL=https://rss.example.com/
      - RUN_MIGRATIONS=1
      - CREATE_ADMIN=1
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=CHANGE_ME_TOO
      - POLLING_FREQUENCY=60
    healthcheck:
      test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"]
    mem_limit: 128m
  db:
    image: postgres:18
    restart: unless-stopped
    environment:
      - POSTGRES_USER=miniflux
      - POSTGRES_PASSWORD=CHANGE_ME
      - POSTGRES_DB=miniflux
    volumes:
      - miniflux-db:/var/lib/postgresql
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "miniflux"]
      interval: 10s
      start_period: 30s
    mem_limit: 192m
volumes:
  miniflux-db:

该文件中有 3 行最容易写错。LISTEN_ADDR=0.0.0.0:8080重复了官方镜像 Dockerfile 中已有的设置,因此配合 miniflux/miniflux 时只是无害的保护措施,并不能修复问题。在构建自有镜像或运行打包的二进制文件时,这一设置很重要,因为该二进制文件文档中的默认值是 127.0.0.1:8080。容器内绑定到 loopback 的进程无法通过发布端口访问,因此容器看似正常运行,但连接会被重置。卷路径 /var/lib/postgresql与 PostgreSQL 18 匹配;版本 17 及更早版本将数据存储在 /var/lib/postgresql/data。挂载错误的路径意味着数据目录根本不在卷上,因此下次重新创建容器时,所有数据都会消失。127.0.0.1:8080:8080使端口不会暴露到公网,因为发布端口时如果不指定地址,Docker 会将规则写入 ufw 不管理的链。Docker 端口会绕过 ufw解释了这一机制,使用 Traefik 反向代理则说明如何在其前面配置 TLS。

docker compose up -d
docker compose ps
docker compose logs -f miniflux
docker stats --no-stream

docker compose ps应列出两个正在运行的服务,并将数据库标记为 healthy。Miniflux 第一次启动时会记录架构迁移日志,这就是 RUN_MIGRATIONS=1触发的操作。docker stats --no-stream会输出实时内存列,该数值应与上方图表中的上限进行比较。如果 Miniflux 容器反复重启,请查看其日志:connect: connection refused表示它在 PostgreSQL 准备好接受连接之前就已启动,而 service_healthy条件正是为了阻止这种情况,因此请检查你编辑文件后该条件是否仍然存在。如果你不熟悉 Compose,VPS 上的 Docker Compose 基础会先介绍文件布局。

1 GB 服务器无法容纳的服务

Tiny Tiny RSS 应跳过。其官方的四服务架构可以运行在 1 GB VPS 上,但前提是该 VPS 不运行其他服务。它无法与另一个依赖数据库的应用和反向代理共存。四个服务意味着四组开销,其中一个服务还是 PostgreSQL。

CommaFeed 可以运行,但只能使用 H2 镜像,并设置为项目示例中的 256 MB 上限。让小型服务器无法承受的组合,是 CommaFeed 与独立数据库服务器同时运行。-jvm 镜像变体会进一步增加内存压力,因为项目文档警告,JVM 默认会积极占用内存,并且不会将未使用的内存归还给操作系统。latest-h2 和 latest-postgresql 标签是原生构建版本,项目建议使用它们以降低内存占用。因此,除非有理由运行 JVM,否则应使用这些版本。

服务器内存耗尽时,内核的内存不足终止程序会选择一个进程并终止它。dmesg -T 会显示类似 Out of memory: Killed process 1234 (java) 的行,而容器会直接从 docker compose ps 中消失,应用日志中不会留下任何消息,因为应用根本没有机会写入日志。

各服务的升级方式

  • Miniflux:使用 docker compose pull && docker compose up -d,并在设置 RUN_MIGRATIONS=1 时于启动阶段应用架构迁移。升级风险不在 Miniflux,而在其底层的 PostgreSQL 主版本。
  • FreshRSS:拉取新镜像。使用 SQLite 时无需升级数据库引擎,因此常见故障通常来自未及时更新的第三方扩展。
  • CommaFeed:拉取与数据库匹配的镜像变体。从 latest-h2 切换到 latest-postgresql 不会迁移现有数据。
  • yarr:替换二进制文件,并保留数据库文件。2026 年 6 月、7 月和 9 月均有版本发布;截至 2026 年 10 月,v2.9 是最新版本,因此应不时检查发布页面。
  • Tiny Tiny RSS:docker compose pull && docker compose up -d。应用容器会在启动时自行更新。项目 FAQ 将架构更新错误归因于卷或覆盖配置损坏,因此出现此类错误时应先检查这些设置。如果 compose 文件仍从已停用的 tt-rss.org 项目拉取镜像,请切换到该分支的镜像(Docker Hub 上的 supahgreg/tt-rss 或 ghcr.io/tt-rss/tt-rss)。

在执行任何升级前都应创建数据库转储,而不是升级后再创建。

docker compose exec -T db pg_dump -U miniflux miniflux | gzip > miniflux-$(date +%F).sql.gz

刷新间隔的带宽成本

下面的数字是算术结果,不是实测数据。计算假设有 100 个订阅源,每个间隔请求每个订阅源 1 次,每次响应大小为 40 KB。服务器遵循条件请求时,实际流量通常更低;订阅源包含完整文章正文时,实际流量会更高。

图表Monthly fetches and bandwidth for 100 feeds at 40 KB per response
此图表背后的数据
[
  {
    "label": "Every 5 minutes",
    "fetches_per_month": "864,000",
    "gb_per_month": 34.6
  },
  {
    "label": "Every 15 minutes",
    "fetches_per_month": "288,000",
    "gb_per_month": 11.5
  },
  {
    "label": "Every 30 minutes",
    "fetches_per_month": "144,000",
    "gb_per_month": 5.8
  },
  {
    "label": "Every 60 minutes",
    "fetches_per_month": "72,000",
    "gb_per_month": 2.9
  }
]

对 100 个订阅源每 5 分钟刷新一次,每月会产生 864,000 次请求,流量约为 34.6 GB。每小时轮询一次会产生 72,000 次请求,流量约为 2.9 GB。Miniflux 默认将 POLLING_FREQUENCY 设置为 60 分钟,这对应图表的最后一行,适合几乎所有用户。请求频率更高,并不会让文章更早到达。

条件请求可以让实际流量低于算术结果。阅读器保存订阅源返回的 ETag 和 Last-Modified 响应头后,会将它们作为 If-None-Match 和 If-Modified-Since 发回;如果服务器没有新内容,就会以 304 Not Modified 响应且不返回正文。建立连接仍会产生握手开销,但不会传输正文。忽略条件请求的订阅源每次都会返回完整文档,因此少数较大的订阅源就可能单独占用大部分传输流量。

轮询过于频繁还可能导致您被封禁。服务器认定您正在频繁请求时,会返回 429 Too Many Requests;有些站点则会返回 403。Miniflux 会将最近一次错误记录在订阅源自身上。因此,当一个订阅源停止更新而其他订阅源仍正常工作时,应首先查看订阅源列表。

订阅源会失效,OPML 文件不是备份

订阅源失效的速度比预期更快。域名会过期,网站会迁移到不提供订阅源的平台,原本提供 XML 的 URL 也可能开始返回带有 200 OK 状态码的 HTML 错误页面。最后一种情况最棘手:抓取成功,但解析失败,阅读器记录的是解析错误,而不是网络错误。每年检查一次订阅源列表,按最后更新时间排序,删除已停止更新的订阅源。

OPML 导出文件只是订阅列表。标准 OPML 文件包含订阅源 URL 和文件夹名称。FreshRSS 会添加自己的 XML 命名空间,其中还包含每个订阅源的设置,例如刷新间隔、XPath 抓取选择器和自动标记已读过滤器;但任何 OPML 导出文件都不会保存已读状态、加星文章或您保存的文章正文。将该 OPML 文件导入全新安装后,订阅源会恢复,但您以前读过的所有文章都会再次标记为未读。

真正重要的备份是数据库。对于 PostgreSQL,上面的 pg_dump 命令即可完成全部操作。对于 FreshRSS 或 yarr 这样的 SQLite 阅读器,应先停止写入进程并复制文件;也可以在服务运行时使用 sqlite3 yarr.db ".backup '/tmp/yarr-backup.db'" 创建一致的副本。对正在写入的数据库直接执行普通 cp,可能生成之后无法打开的文件,因为复制过程可能捕获到未完成的写入。然后按计划将这些文件推送到服务器之外,这正是 VPS 上的 restic 备份 的用途。至少要将其中一个备份恢复到临时容器中,确认恢复流程确实可用。

订阅源阅读器是最容易自行运行的服务之一,因此它会出现在所有 2026 年值得自行托管的服务列表中。在旁边部署 自行托管的 SearXNG 实例,阅读和搜索都可以保留在您控制的硬件上。

FAQ

哪个自托管 RSS 阅读器占用内存最少?

yarr。它是一个内置 SQLite 的单个 Go 二进制文件,因此不需要数据库服务器,也不需要额外的语言运行时;设置 128 MB 的上限即可稳定运行。代价是功能较少:它只支持 Fever API,最新版本是 2026 年 9 月发布的 v2.9。如果您需要 Google Reader API 支持和全文搜索,同时希望保持类似的资源占用,那么将 Miniflux 与 PostgreSQL 的内存上限设为 320 MB 是更好的选择。

可以在 1 GB VPS 上运行自托管 RSS 阅读器吗?

可以。为两个容器都设置 mem_limit 后,Miniflux 与 PostgreSQL 的内存占用约为 320 MB;FreshRSS 使用 SQLite 时可以运行在单个容器中。1 GB VPS 上应避免使用官方 Tiny Tiny RSS 方案,因为它包含 4 个服务,其中还包括自带的 PostgreSQL。务必设置内存限制,因为内存未受限的容器运行在内存已耗尽的主机上时,内核会终止某个进程,而被选中的通常是数据库进程,不一定是出问题的应用进程。

其中哪些可以与 iOS 和 Android RSS 应用配合使用?

Miniflux、FreshRSS 以及 CommaFeed 7.3.0 或更高版本同时支持 Fever 兼容 API 和 Google Reader 兼容 API,因此几乎所有移动客户端都可以连接。yarr 仅支持 Fever API。Tiny Tiny RSS 使用自有 API,因此需要使用专用客户端。在 FreshRSS 中,您还必须在 Authentication 下启用 API 访问,并在个人资料中设置单独的 API 密码;否则应用会登录失败,但网站仍可正常使用。

OPML 导出是否等同于 RSS 阅读器备份?

不是。OPML 可以重建订阅列表,FreshRSS 的扩展导出还会包含每个订阅源的设置和过滤器,但已读状态、加星项目和文章正文都存储在数据库中。对于 PostgreSQL,请使用 pg_dump 备份数据库本身;对于 SQLite,请使用 .backup 命令,然后将备份结果复制到服务器之外。

Miniflux 是否支持 SQLite?

不支持。项目文档说明它“仅支持 PostgreSQL”;全文搜索依赖 PostgreSQL 的功能,因此无法切换到更轻量的模式。如果您需要完全不运行数据库容器的 RSS 阅读器,可以让 FreshRSS 使用默认的 SQLite 后端,或使用带嵌入式文件的 yarr。