VPS向けセルフホストRSSリーダー5選を比較
Miniflux、FreshRSS、CommaFeed、yarr、Tiny Tiny RSSをVPSで比較します。必要メモリ、PostgreSQLやSQLiteなどのデータベース、FeverとGoogle Reader API対応、アップグレードの違いを確認できます。
小規模 VPS に適したセルフホスト型 RSS リーダー
Miniflux は、小規模 VPS に導入するセルフホスト型 RSS リーダーです。PostgreSQL と組み合わせて動作する Go バイナリ 1 つで構成できます。Fever API と Google Reader API に対応しているため、サードパーティー製のスマートフォンアプリから接続できます。アップグレードも docker compose pull 1 つで完了します。拡張機能が必要で、SQLite を内蔵した 1 つのコンテナにまとめたい場合は、FreshRSS を選びます。
VPS のディスク容量を使う価値があるリーダーは、Miniflux、FreshRSS、CommaFeed、yarr、Tiny Tiny RSS の 5 つです。このページでは、これらの実際の違いを比較します。各スタックに必要なメモリ量、使用するデータベース、スマートフォンアプリに必要な同期 API、アップグレード時の動作を確認します。ここに示す数値は、プロジェクトが公開している値か、単純な算術から算出した値のいずれかです。どちらに該当するかは本文で示します。これらは使用するハードウェアのベンチマークではないため、docker stats を使って自分のサーバーを測定してください。
5つのリーダーを1段落ずつ
Miniflux は Go で記述され、静的コンパイル済みの単一バイナリとしてリリースされています。ドキュメントでは、唯一の必須依存関係について「PostgreSQL でのみ動作する」と明記されています。SQLite モードはありません。REST API、Fever 互換 API、Google Reader 互換 API に加え、OPML のインポートとエクスポートに対応しています。全文検索は PostgreSQL に任せます。これがデータベースを省略できない理由の1つです。
FreshRSS は PHP 製で、Web サーバーとアプリケーションを1つのコンテナに収めて動作します。デフォルトのデータベースは SQLite で、別のサービスを必要としません。大規模な構成向けに PostgreSQL と MySQL もサポートしています。Google Reader API と Fever API に対応しています。インストール手順は FreshRSS を VPS に導入する手順 で説明済みです。そのため、このページではインストールを繰り返さず、比較に集中します。
CommaFeed は Quarkus 上で動作する Java アプリケーションで、Google Reader に似た構成を採用しています。データベースは実行時ではなくビルド時に選択します。そのため、プロジェクトはデータベースごとに別のイメージを公開しています。組み込み H2 データベース用が athou/commafeed:latest-h2、PostgreSQL 用が athou/commafeed:latest-postgresql で、MySQL と MariaDB 用のバリエーションもあります。REST API と Fever 互換 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 に対応しています。最新のタグ付きリリースは v2.8 で、2024 年 7 月のものです。2026 年 8 月に確認した時点では、積極的に開発されているソフトウェアではなく、完成済みのソフトウェアとして扱うべきです。
Tiny Tiny RSS は5つの中で最も古く、運用も最も複雑です。公式の Docker 構成は4つのサービスで構成されます。PostgreSQL コンテナ、PHP-FPM アプリケーションコンテナ、フィードを取得する独立した updater コンテナ、そして前段の nginx コンテナです。ドキュメントには「この構成では PostgreSQL を使用する」と明記されています。独自の JSON API を備えており、Android クライアントや複数のサードパーティーアプリがこの API を使用します。Fever は対応していません。
各スタックに必要なメモリ量
以下の数値は実測値ではなく、予算値です。小規模な VPS で各スタックが超えないようにするメモリ上限を示します。CommaFeed の数値は、プロジェクトが公開している例に基づくもので、コンテナの上限を 256 MB に設定しています。その他の数値は、フィード取得処理のための余裕を残した上限です。フィード取得処理は、更新サイクルの開始時にメモリ使用量が急増します。
The data behind this chart
[
{
"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 は、単一のバイナリと 1 つの SQLite ファイルだけで動作し、データベースサーバーや言語ランタイムを必要としないため、128 MB と最も少ないメモリで済みます。Miniflux は 320 MB を 2 個のコンテナで使用し、その大部分は Miniflux ではなく PostgreSQL が占めます。Tiny Tiny RSS は例外的に、640 MB を 4 個のコンテナで使用します。アプリケーション、アップデーター、データベース、Web サーバーが 4 つの独立したプロセスとして動作し、それぞれが独立したヒープを持つためです。
これらの値は、希望値ではなく実際の制限値として設定してください。Docker Compose でのメモリ制限では、構文と、コンテナが上限に達したときの動作を説明しています。制限のないコンテナは、ホストのメモリが枯渇しても穏やかに停止しません。カーネルが停止対象のプロセスを選んで強制終了し、そのプロセスは負荷の原因となったコンテナとは限りません。
各読者が選ぶことになるデータベース
この5つの中で、運用上の違いが最も大きいのはデータベースです。ユーザーインターフェースの違いよりも重要な判断です。バックアップ手順とアップグレード時のリスクが決まるためです。
Miniflux と公式の Tiny Tiny RSS 構成では PostgreSQL が必要です。完全な全文検索と、安全な同時書き込みを利用できます。一方で、2つ目のコンテナとボリュームが必要になります。また、継続的に発生する問題が1つあります。公式の PostgreSQL イメージは、メジャーバージョン間でデータをインプレース移行できません。Tiny Tiny RSS のドキュメントにも明記されており、「公式の PostgreSQL コンテナは、メジャーバージョン間のデータ移行をサポートしていない」と警告しています。現実的な選択肢は、古いメジャーバージョンを固定するか、pg_dump と pg_restore を使ってダンプとリストアを行うことです。1年または2年に1回はこの作業が必要になる前提で計画してください。
SQLite は FreshRSS と yarr のデフォルトです。ファイル1つで動作し、サーバー、ポート、パスワードは必要ありません。数百件のフィードを1人で利用する構成なら十分に対応できます。複数のユーザーが同時に書き込むと遅くなります。その場合は、FreshRSS の PostgreSQL オプションを使うメリットが出てきます。yarr は v2.7 でオプションの PostgreSQL サポートを追加しましたが、通常は組み込みファイルで運用します。
H2 は CommaFeed に組み込まれているデフォルトのデータベースです。開始前に検討しておく必要があります。CommaFeed はイメージのビルド時にデータベースを選択するためです。後から H2 から PostgreSQL に移行する場合、設定変更だけでは済みません。別のイメージを用意し、自分でデータ移行を実行する必要があります。1年分の閲覧履歴を保存する前に決めてください。
スマートフォンアプリは動作しますか
この点は、予想以上に重要です。フィードリーダーは、Web インターフェースだけで利用するものではないためです。
Miniflux は Fever 互換 API と Google Reader 互換 API に対応しているため、ほとんどの iOS および Android クライアントから接続できます。FreshRSS も同じ 2 つの API に対応しています。FreshRSS のドキュメントでは、Google Reader API はすべての機能をサポートする「best」、Fever API は「limited features and less efficient」と評価されています。FreshRSS では、アプリからログインする前に 2 つの手順も必要です。Authentication の「Allow API access (required for mobile apps)」を有効にし、ユーザープロファイルで API パスワードを作成します。API パスワードの作成を省略すると、Web ログインは動作する一方で、アプリでは認証エラーになります。確認箇所を知らないと、原因が分かりにくい問題です。
CommaFeed と yarr は Fever 互換 API のみを公開しています。そのため、Fever に対応したクライアントでは動作しますが、Google Reader にしか対応していないアプリでは動作しません。Tiny Tiny RSS は独自の API を使用するため、Tiny Tiny RSS 用に作られたクライアントが必要です。300 個のフィードをインポートする前に、使用したいアプリがそのフィードリーダーに対応していることを確認してください。
1 GB のサーバーで動作する compose ファイル
これは、2026 年 8 月時点のプロジェクト独自の Docker 例を基にした Miniflux スタックです。公開ポートは 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 を設定するのは、バイナリのドキュメント上のデフォルト値が 127.0.0.1:8080 だからです。コンテナ内で loopback にバインドされたプロセスには、公開ポート経由で接続できません。そのため、コンテナが正常に見えても接続がリセットされます。ボリュームのパス /var/lib/postgresql は PostgreSQL 18 に対応しています。バージョン 17 以前ではデータが /var/lib/postgresql/data に保存されます。誤ったパスをマウントすると、データディレクトリがボリューム上に配置されません。その結果、コンテナを再作成するたびにデータがすべて消えます。127.0.0.1:8080:8080 により、ポートをパブリックインターネットから隔離できます。アドレスを指定せずにポートを公開すると、ufw が管理しないチェーンにルールが追加されるためです。Docker のポートは ufw を迂回するでは、この仕組みを説明しています。Traefik のリバースプロキシを使うと、その前段に TLS を配置できます。
docker compose up -d
docker compose ps
docker compose logs -f miniflux
docker stats --no-streamdocker compose ps には、両方のサービスが running として表示され、データベースには healthy が付いているはずです。Miniflux の初回起動ではスキーマのマイグレーションがログに出力されます。これは RUN_MIGRATIONS=1 が実行する処理です。docker stats --no-stream は現在のメモリ使用量の列を表示します。この値を、上の表にある上限と比較します。Miniflux コンテナがループして再起動する場合は、ログを確認してください。connect: connection refused は、PostgreSQL が接続を受け付ける準備が整う前に Miniflux が起動したことを示します。これは service_healthy の条件が防ぐ状態です。そのため、編集後もこの条件が残っていることを確認してください。Compose を初めて使う場合は、まず VPS での Docker Compose の基本でファイル構成を確認できます。
1 GB のサーバーには収まらないもの
Tiny Tiny RSS は候補から外してください。公式の 4 サービス構成は、その VPS でほかの処理を実行しない場合に限り、1 GB の VPS で動作します。別のデータベースを使用するアプリケーションやリバースプロキシと同時に実行することはできません。4 サービスではオーバーヘッドも 4 セット必要になり、そのうち 1 つは PostgreSQL です。
CommaFeed は動作しますが、H2 イメージと、プロジェクト独自の例で設定されている 256 MB の上限が必要です。小さなサーバーで問題になるのは、JVM と別のデータベースサーバーを組み合わせる構成です。JVM は、残しておいたメモリの余裕を使い切るためです。CommaFeed のドキュメントは -Xmx256m をハードリミットとして示し、OpenJ9 を「HotSpot JVM よりメモリ効率の高い代替」と説明しています。これは、メモリがどこで消費されるかを示しています。
サーバーのメモリが不足すると、カーネルの out of memory killer がプロセスを選択して終了させます。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: 新しいイメージを pull します。SQLite ではアップグレードするデータベースエンジンがないため、通常の問題は、更新に追随していないサードパーティー拡張機能から発生します。
- CommaFeed: データベースに合ったイメージバリアントを pull します。
latest-h2からlatest-postgresqlへ切り替えても、データは移行されません。 - yarr: バイナリを置き換え、データベースファイルは保持します。2024 年 7 月の v2.8 以降リリースがなく、2026 年 8 月時点で確認した限り、通常はアップグレードするものがありません。
- Tiny Tiny RSS:
docker compose pull && docker compose up -dです。スキーマのマイグレーションは自動的に実行されます。確認が必要な場合、インターフェースからマイグレーション画面へリダイレクトされます。
これらのいずれの場合も、実行後ではなく実行前にデータベースをダンプしてください。
docker compose exec -T db pg_dump -U miniflux miniflux | gzip > miniflux-$(date +%F).sql.gzリフレッシュ間隔にかかる帯域幅
以下の数値は実測値ではなく、算術計算によるものです。100 個のフィードを対象に、各間隔でフィードごとに 1 回リクエストし、レスポンスが 40 KB であると仮定しています。サーバーが条件付きリクエストに対応している場合、実際の通信量は少なくなります。フィードに記事本文全体が含まれる場合は、通信量が多くなります。
The data behind this chart
[
{
"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 分間隔で取得すると、1 か月あたり 864,000 リクエスト、約 34.6 GB になります。1 時間間隔では 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 はフィードごとに最後のエラーを記録します。そのため、他のフィードは更新されているのに 1 つのフィードだけ更新されなくなった場合は、最初にフィード一覧を確認します。
フィードは停止し、OPML ファイルはバックアップになりません
フィードは予想より早く使えなくなります。ドメインの期限が切れたり、サイトがフィードを提供しないプラットフォームへ移行したりします。以前は XML を返していた URL が、200 OK ステータスの HTML エラーページを返すこともあります。最後のケースは扱いにくい問題です。取得自体は成功しますが、解析に失敗するため、リーダーにはネットワークエラーではなく解析エラーが記録されます。年に 1 回、フィード一覧を最終更新日時で並べ替え、長期間更新されていないフィードを削除してください。
OPML のエクスポートは購読一覧です。フィード URL とフォルダー名が保存されます。既読状態、スターを付けた記事、フィードごとの設定、フィルタールール、保存した記事本文は保存されません。その OPML を新しいインストール環境にインポートすると、フィードは復元できますが、これまで読んだすべての記事が再び未読として表示されます。
重要なのはデータベースのバックアップです。PostgreSQL では、前述の pg_dump コマンドだけで完了します。FreshRSS や yarr などの SQLite リーダーでは、書き込みを停止してファイルをコピーするか、稼働中に sqlite3 yarr.db ".backup '/tmp/yarr-backup.db'" を使って一貫性のあるコピーを取得してください。書き込み中のデータベースに対して単純な cp を実行すると、書き込み途中の状態がコピーされ、後で開けないファイルが生成されることがあります。次に、スケジュールを設定してそれらのファイルをサーバー外へ転送します。これは VPS 上の restic バックアップ を利用する目的の 1 つです。少なくとも 1 回はスクラッチコンテナへ復元し、手順が機能することを確認してください。
フィードリーダーは自分で運用するサービスとして特に低コストです。そのため、2026 年に自分でホスティングする価値があるものの一覧には必ず含まれています。隣に 自分でホスティングする SearXNG インスタンスを配置すれば、読書と検索の両方を自分で管理するハードウェア上で行えます。
FAQ
メモリ使用量が最も少ない self-hosted RSS リーダーはどれですか?
yarr です。SQLite を組み込んだ単一の Go バイナリであり、別途データベースサーバーや言語ランタイムが不要なため、128 MB の上限で余裕を持って運用できます。一方で、保守性と機能には制約があります。最新リリースは 2024 年 7 月の v2.8 で、対応しているのは Fever API だけです。同程度のリソース使用量で、活発に開発されているプロジェクトを選ぶなら、PostgreSQL と組み合わせた Miniflux を 320 MB で運用する構成が適しています。
1 GB の VPS で self-hosted RSS リーダーを実行できますか?
はい。Miniflux と PostgreSQL は、両方のコンテナで mem_limit を設定すれば、約 320 MB に収まります。FreshRSS と SQLite は 1 つのコンテナに収まります。1 GB 環境で避けるべきなのは、公式の Tiny Tiny RSS スタックです。自身の PostgreSQL を含めて 4 個のサービスで構成されるためです。必ずメモリ上限を設定してください。メモリを使い切ったホストで上限のないコンテナを実行すると、カーネルがプロセスを強制終了します。その対象は、問題の原因であるアプリケーションではなく、データベースになることがよくあります。
これらのうち、iOS と Android の RSS アプリに対応しているものはどれですか?
Miniflux と FreshRSS は、Fever 互換 API と Google Reader 互換 API の両方に対応しているため、ほぼすべてのモバイルクライアントから接続できます。CommaFeed と yarr が対応しているのは Fever API だけです。Tiny Tiny RSS は独自 API を使用するため、専用に作られたクライアントが必要です。FreshRSS では、Authentication の下で API アクセスを有効にし、プロファイルで別の API パスワードも設定する必要があります。設定しないと、Web サイトにはログインできても、アプリのログインは失敗します。
OPML のエクスポートは RSS リーダーのバックアップになりますか?
いいえ。OPML に保存されるのはフィード URL とフォルダーだけです。そのため、購読リストは復元できますが、それ以外は復元できません。既読状態、スター付きアイテム、フィルタールール、記事本文はすべてデータベースに保存されています。PostgreSQL では pg_dump を使用し、SQLite では .backup コマンドを使用して、データベース自体をバックアップしてください。作成したバックアップはサーバーの外部にもコピーします。
Miniflux は SQLite に対応していますか?
いいえ。プロジェクトのドキュメントには「PostgreSQL でのみ動作する」と記載されています。全文検索も PostgreSQL の機能で実装されているため、より軽量なモードに切り替えることはできません。データベースコンテナをまったく使わないフィードリーダーが必要な場合は、デフォルトの SQLite バックエンドを使用する FreshRSS、または組み込みファイルを使用する yarr を実行してください。