MinifluxでRSSリーダーを自前化する|Google NewsをRSSで読む
自宅のUbuntuサーバーにMinifluxを立てて、有料のクラウドRSSサービスの代わりに自分専用のRSSリーダーを持つ手順です。本体とPostgreSQLの2コンテナ構成、ポート8750と更新間隔10分などの設定値、RSSHubとGoogle NewsのRSSで情報源を集約する方法、全文取得(Fetch original content)、Tailscale経由の外部アクセス、Claude Codeへの指示書までまとめました。
目次
はじめに
気になるサイトの更新を、広告やおすすめに邪魔されずに、自分のペースで追いたいと思ったことはありませんか。
私は情報収集にRSSリーダーを使っています。
RSSというのは、サイトの新着記事を決まった形式で受け取れる仕組みのことで、これを使うと、たくさんのサイトの更新を一か所にまとめて読めます。
長らく「Inoreader」という定番のクラウドRSSサービスを有料で使っていたのですが、使い込むほどに「毎月お金を払い続けて、しかも自分の購読データをよその会社に預けっぱなしにするのは、もったいないな」と感じるようになりました。
ちょうど自宅サーバーを立てたところだったので、これを機にRSSリーダーも自前に移そうと考えました。
結論として、Miniflux(ミニフラックス)という無料のソフトで、RSSリーダーを自前のサーバーに立てられました。
さらに、RSSが用意されていないサイトや、Google Newsの検索結果まで、自分のリーダーに取り込めるようにしました。
この記事では、私が実際に動かしている設定値(ポート番号・更新間隔・環境変数)と、コピーして使える構成ファイルまで具体的に書きます。
記事の後半には、面倒な作業を任せるためのClaude Codeへの指示書も載せておきます。
前提として、UbuntuとDockerまで用意した自宅サーバーの土台があるものとして進めます。
外からのアクセスにはTailscaleを使うので、そちらも入っている前提です。
なお、Miniflux単体は軽くて快適な一方、見た目と読み心地はInoreaderにはまだ及びません。
そこを埋めるために作ったObsidianプラグインの話は、最後に少しだけ触れます。
Minifluxとは何か
Minifluxは、自分のサーバーの上に立てられる、無料で軽量なRSSリーダーです。
特徴は、とにかく「速くて、シンプルで、軽い」ことです。
よけいな飾りがなく、広告も、アルゴリズムによる「おすすめ」もありません。
自分が登録した情報源の更新だけが、新しい順に並びます。
動作も軽く、私の環境(Core i5-6400・メモリ8GBの中古機)では、Miniflux本体の使用メモリは常時100MB前後で収まっています。
そして、どのフィードを登録したか・どの記事を読んだかというデータが自分のサーバーに保存されるのがポイントです。
Inoreaderとの違い
ふだんクラウドのRSSサービスを使っている方向けに、違いを整理します。
- 保存場所:Inoreaderはよその会社のサーバー、Minifluxは自分の家のサーバーにデータがあります。
- 料金:Inoreaderは本格利用だと有料です。Minifluxはソフト自体が無料で、かかるのは電気代くらいです。
- 動作の軽さ:Minifluxは非常に軽量で、非力なサーバーでもサクサク動きます。
- シンプルさ:高機能なクラウドサービスに比べると機能は絞られていますが、その分、迷わず使えます。
Minifluxは「本体」と「データベース」の2つで動く
ひとつ知っておくとよいのが、Minifluxは本体と「データベース」の2つの部品が連携して動くという点です。
登録したフィードや既読の情報を記録しておくために、データベースが一緒に必要になります。
私の環境では PostgreSQL(ポストグレスキューエル)17系 を使っています。
つまり、Dockerのコンテナ(アプリの箱)を2つ立てて、組にして動かします。
- 本体のコンテナ:イメージは
miniflux/miniflux:latest。画面とフィードの取得を担当します。 - データベースのコンテナ:イメージは
postgres:17。フィードや既読の記録を保存します。
この2つは、後で出てくる構成ファイルの中で、本体が DATABASE_URL という設定を通じてデータベースに接続します。
「Minifluxは本体+DBの2コンテナで1セット」とだけ覚えておけば大丈夫です。
ステップ1:MinifluxとデータベースをDockerで立てる
CasaOSのアプリ管理画面からでも入れられますが、ここでは何を設定しているかが分かる構成ファイル(docker compose)で示します。
中身が分かれば、CasaOSの画面で同じ値を入れるのも、Claude Codeに作ってもらうのも簡単になります。
私が実際に動かしているのは、おおむね次の内容です。
services:
miniflux:
image: miniflux/miniflux:latest
ports:
- "8750:8080" # 家の中では http://(サーバーのIP):8750 で開く
environment:
- DATABASE_URL=postgres://miniflux:your_db_password@db/miniflux?sslmode=disable
- RUN_MIGRATIONS=1 # 初回起動時にDBの表を自動で作る
- POLLING_FREQUENCY=10 # 10分おきに各サイトへ新着を取りに行く
- MANUAL_REFRESH_MIN_INTERVAL=5 # 手動更新ボタンの最短間隔(分)
- LISTEN_ADDR=0.0.0.0:8080
depends_on:
- db
restart: unless-stopped
db:
image: postgres:17
environment:
- POSTGRES_DB=miniflux
- POSTGRES_USER=miniflux
- POSTGRES_PASSWORD=your_db_password # ← DATABASE_URL の your_db_password と同じ値にする
volumes:
- miniflux-db:/var/lib/postgresql/data
restart: unless-stopped
volumes:
miniflux-db:
設定の意味を、効いてくる順に説明します。
ports: "8750:8080":Miniflux本体は箱の中では8080番で待っていますが、それを家のネットワークからは 8750番 で開けるようにしています。番号は何でもよいのですが、他のアプリと重ならない番号を選びます。家の中からはhttp://(サーバーのIP):8750でアクセスします。DATABASE_URL:本体がデータベースに接続するための住所です。miniflux:your_db_passwordはDBのユーザー名とパスワード(your_db_passwordは自分で決めた値に置き換え、下のPOSTGRES_PASSWORDと必ず揃える)、@dbは相手のコンテナ名(下のdb:を指す)です。末尾のsslmode=disableは「暗号化通信を使わない」指定で、同じサーバー内の箱どうしの通信なので付けています。RUN_MIGRATIONS=1:初回起動のときに、データベースの中に必要な表(テーブル)を自動で作る指定です。これが無いと、自分で作成コマンドを打つ手間が発生します。POLLING_FREQUENCY=10:各サイトへ新着を取りに行く間隔を10分にしています。短くすれば新着に早く気づけますが、その分こまめに相手サイトへ取りに行くことになります。10分なら体感ほぼ即時で、相手サイトにも負担をかけすぎない、ちょうどよい折り合いだと感じています。MANUAL_REFRESH_MIN_INTERVAL=5:画面の「更新」ボタンを連打しても、最短5分はおいてからしか取りに行かない、という安全弁です。volumes: miniflux-db:データベースの中身を保存する場所です。コンテナを作り直してもフィードや既読が消えないよう、名前付きの保存領域に置いています。
ひとつ補足です。
このデータベースの保存場所は、写真などを置く /DATA ではなく、Docker専用の保存領域にあります。
「じゃあバックアップから漏れるのでは」と思うかもしれませんが、データベースはファイルを単純コピーすると壊れることがあるため、外付けHDDへ自動バックアップする仕組みのほうで pg_dumpall という専用コマンドで安全に書き出して、/DATA 配下のバックアップに含めています。
なので、ここは名前付き保存領域のままで大丈夫です。
ステップ2:最初のログイン用ユーザーを作る
Minifluxは、最初に管理者のユーザーを1人作って使い始めます。
本体のコンテナが起動したら、サーバーで次のコマンドを1回だけ実行します。
docker exec -it miniflux /usr/bin/miniflux -create-admin
ユーザー名とパスワードを聞かれるので入力すれば、管理者ユーザーができます(コンテナ名は構成によって変わるので、docker ps で本体側の名前を確認してください)。
あとはブラウザで http://(サーバーのIP):8750 を開き、いま作ったユーザーでログインすると、まだ何も登録されていない、まっさらな画面が表示されます。
操作はとてもシンプルです。
記事の一覧から読みたいものを開き、読み終わったら既読にする。
j k キーで次/前の記事へどんどん送っていけます。
慣れると、大量の更新もあっという間にさばけます。
ステップ3:購読したいサイトを登録する
情報源(フィード)の登録は簡単です。
読みたいサイトのRSSのアドレス(URL)を、Minifluxの「フィードを追加」の画面に貼り付けるだけです。
多くのニュースサイトやブログはRSSのアドレスを公開していて、サイトのトップページのアドレスを入れるだけで、Minifluxが自動でRSSを見つけてくれることも多いです。
登録したフィードは、カテゴリ(「ニュース」「技術」「趣味」など)に分けて整理できます。
ステップ4:RSSが無いサイトやGoogle Newsも取り込む
ここからが応用編で、私がいちばん工夫したところです。
世の中には、RSSのアドレスを公開していないサイトもありますし、「特定のキーワードのニュースをまとめて追いたい」こともあります。
私は、Minifluxへの取り込み口を3段構えにして、ほぼあらゆる情報源を集約できるようにしました。
1. RSSがあるサイトは、そのまま登録する。
これは前のステップのとおりです。
2. RSSが無いサイトは、RSSHubでRSS化する。
RSSHub(アールエスエスハブ)は、RSSを公開していないサイトを、決められた住所(ルート)に当てはめてRSS化してくれる汎用の変換ツールです。
これも自分のサーバーにDockerで立てます。
私の構成はこうです。
services:
rsshub:
image: diygod/rsshub:latest
ports:
- "1200:1200"
environment:
- NODE_ENV=production
- CACHE_TYPE=redis
- REDIS_URL=redis://redis:6379/
- CACHE_EXPIRE=300 # 取得結果を5分キャッシュする(秒)
- REQUEST_TIMEOUT=30000 # 1サイト30秒でタイムアウト(ミリ秒)
- TZ=Asia/Tokyo
depends_on:
- redis
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- rsshub-redis:/data
restart: unless-stopped
volumes:
rsshub-redis:
ポイントは2つです。
RSSHubは取得結果を一時的に覚えておく置き場として Redis とセットで動かします(CACHE_TYPE=redis)。
CACHE_EXPIRE=300 で、一度取りに行った結果を5分間は使い回すので、同じフィードを連続で開いても相手サイトに何度も行きません。
REQUEST_TIMEOUT=30000 は、重いサイトでも30秒は待つ、という指定です。
使い方は、たとえば「あるYouTubeチャンネルの新着動画」なら /youtube/channel/(チャンネルID)、というように、サービスごとに専用のルート(決まった形の住所)が用意されています。
そのルートを、自分のRSSHubの住所 http://(サーバーのIP):1200/youtube/channel/… の形にして、Minifluxにフィードとして登録します。
どんなサービスのどんなルートが使えるかは、RSSHubの公式サイトに一覧があります。
3. キーワード追跡は、Google NewsのRSSを使う。
実はGoogle Newsは、検索結果をRSSの形で受け取れる仕組みを持っています。
たとえば次のようなアドレスを、Minifluxにフィードとして登録します。
https://news.google.com/rss/search?q=(キーワード)&hl=ja&gl=JP&ceid=JP:ja
(キーワード) を、自分が追いたい言葉(会社名やテーマなど)に置き換えると、そのキーワードに関するニュースがRSSとしてMinifluxに流れ込んできます。
hl=ja&gl=JP&ceid=JP:ja は「日本語・日本向けのニュースを返してね」という指定です。
自作のRSS変換ツールに行き着いた経緯
実はここに、ひとつ技術的な回り道がありました。
最初は、ロイターやブルームバーグといった大手ニュースサイトを直接読みに行って、自前でRSS化する小さなツール(PythonのFastAPIで書いた、Minifluxと同じDockerネットワークにいるWebサービス)を作っていました。
ところが、こうした大手サイトには「Botによる自動アクセス」をはじく仕組み(DataDomeなど)が入っていて、プログラムからの取得がうまくいかなくなりました。
そこで方針を変え、このツールの裏側を「サイトを直接読む」のではなく「そのサイト名やテーマでGoogle Newsを検索して、その結果をRSSにする」形にしました。
Google Newsを一段かませることで、Bot対策に正面からぶつからずに、欲しいニュースを安定して取り込めるようになった、というわけです。
このツールは、Minifluxと同じDockerのネットワークに置いてあります。
だからMinifluxからは、サーバーのIPを気にせず、コンテナ名でそのまま http://news-scraper:8000/reuters のように呼べます。
Minifluxから見ると「ロイターのフィード」「ブルームバーグのフィード」といった普通のRSSの住所に見えますが、その住所を開くと、裏でこのツールがGoogle Newsに問い合わせて、結果をRSSの形に整えて返す、という仕組みです。
もちろんインターネットには公開していません。
アドレスの組み立て方が分からなければ、「このキーワードのGoogle NewsのRSSアドレスを作って」とサーバーに入れたClaude Codeに頼めば用意してくれます。
これで、「RSSがあるサイトはそのまま」「無いサイトはRSSHubで」「キーワード追跡はGoogle News(+自作ツール)で」と、ほぼあらゆる情報源を自分のMinifluxに集約できます。
抜粋しか出ないフィードを全文で読む
RSSには、ひとつ困りごとがあります。
サイトによっては、RSSに記事の冒頭の数行(抜粋)しか載せてくれず、続きはサイトを開かないと読めない、という作りになっていることです。
せっかく一か所に集めても、結局あちこちのサイトを開いて回るのでは、雑音なしで読める良さが半減してしまいます。
Minifluxには、これに対応する「元記事の全文を取りに行く」機能(Crawler)があります。
フィードの編集画面で「Fetch original content」を有効にしておくと、Minifluxが記事の元ページにアクセスして本文を抜き出し、抜粋ではなく全文をその場で読めるようにしてくれます。
本文の抜き出し方を、フィードごとの「Scraper Rules」で微調整することもできるので、いつも抜粋しか出ない情報源は、この設定を入れておくと一覧から離れずに読み切れます。
ちなみに、さきほどのGoogle News経由のフィードも、そのままだと「見出しと短いまとめ」だけのことが多いので、気になる情報源にはこの全文取得を組み合わせると、ぐっと読みやすくなります。
外からアクセスするには(Tailscale経由)
Minifluxの画面も、私はインターネットに直接公開していません。
Tailscaleの回で決めたUFW(ファイアウォール)の方針どおり、8750番の入り口は、自宅LANと自分のTailscale端末からだけ許可しています。
具体的には、こんな2行を入れているイメージです。
sudo ufw allow from <自宅LANの範囲> to any port 8750 proto tcp # 自宅LANから
sudo ufw allow from <Tailscaleの範囲> to any port 8750 proto tcp # Tailscaleの端末から
<自宅LANの範囲> には自宅ネットワークの範囲(ご家庭により異なります。土台を作る回で調べた値)を、<Tailscaleの範囲> にはTailscaleが各端末に割り当てる専用アドレスの範囲(Tailscaleの管理画面やドキュメントで確認できます)を入れます。
こうしておくと、家の中では http://(サーバーのIP):8750、外出先ではTailscaleをオンにして「サーバー名:8750」(たとえば myserver:8750)でアクセスできます。
MinifluxはWebブラウザでスマホからもきれいに読めるので、私は通勤中にスマホのブラウザで、たまったニュースに目を通しています。
Obsidianの中でMinifluxを読む(自作プラグイン)
ひとつ補足です。
Minifluxには、ブラウザで開く以外にもアクセス手段があります。
MinifluxはREST API(プログラムから操作する窓口)を備えているので、それを叩けば、別のアプリの中に記事を取り込んで読むこともできます。
私はこれを使って、Minifluxの記事をObsidianの中で読む専用プラグインを自作しました。
設定でMinifluxのサーバーURLとAPIキーを入れるだけで、Obsidianのタブの中にカード型のニュース一覧が並び、メモを書きながら片手間にニュースを消化できます。
Inoreader相当の読み心地を取り戻したかったのと、気になった記事をその場でメモ化(クリッピング)したかったのが、わざわざプラグインまで作った理由です。
さらに、このプラグインには「AIが毎日ニュースを選んで要約してくれるキュレーション」も統合してあります。
このプラグインの中身(リーダー画面・キュレーション・いいね学習)は、Miniflux Readerの記事で詳しく紹介しています。
ここでは「Minifluxは、APIがあるおかげでブラウザ以外の入り口も自由に作れる」とだけ覚えておいてください。
Claude Codeへの指示書
ここまでの構築をやってもらうための、Claude Codeへの指示書です。
サーバーに入れたClaude Codeにこれを渡せば、サーバー側の準備を進めてくれます。
本文で出した値(ポート8750・更新間隔10分・本体+DB・RSSHub+Redis)を、そのまま方針として渡しています。
あなたはこのUbuntuサーバーの構築を手伝うエンジニアです。
私は非エンジニアなので、専門用語は噛み砕いて、操作の前には何をするか一言説明してください。
目的:Inoreaderの代わりに、Minifluxで自分専用のRSSリーダーを立てたい。
RSSの無いサイトやGoogle Newsのニュースも取り込めるようにしたい。
次の手順で進めてください。
1. docker compose で Miniflux本体(miniflux/miniflux:latest)と
PostgreSQL(postgres:17)を組にして起動する。
- 本体は 8750:8080 で公開、POLLING_FREQUENCY=10、RUN_MIGRATIONS=1 を設定。
- DBの保存はnamed volumeにする(バックアップは後でpg_dumpallで取る前提)。
2. miniflux -create-admin で最初の管理者ユーザーを作る手順を案内してほしい。
3. RSSが無いサイト用に、RSSHub(diygod/rsshub:latest)とRedis(redis:7-alpine)も
組にして 1200番で立てる。CACHE_TYPE=redis、CACHE_EXPIRE=300 を設定。
4. UFWで、8750番を自宅LANとTailscaleの範囲からだけ許可する。
インターネットには直接公開しない。
各ステップで、何をしたか・次に私が何をすればいいかを説明してください。
「本体とデータベースがセット」「DBはnamed volume(バックアップはダンプで取る)」「外部公開はしない」という方針を伝えておくのがコツです。
よくあるトラブルと対処
つまずきやすい点をQ&Aでまとめておきます。
Q. ログイン画面が開かない、エラーになる
本体とデータベースのうち、データベース側が起動しきる前に本体が立ち上がると、接続に失敗することがあります。
少し待って本体を再起動するか、docker logs(本体のコンテナ)でエラーを確認します。
DATABASE_URL のパスワードと、DB側の POSTGRES_PASSWORD が食い違っていると必ず失敗するので、まずここを合わせます。
Q. フィードを登録しても記事が出てこない
そのサイトがRSSを公開していない場合があります。
トップページのアドレスでうまくいかないときは、RSSHub経由(http://(サーバーのIP):1200/…)で取り込めないか試してみてください。
新着が反映されないだけなら、POLLING_FREQUENCY の間隔(10分)を待つか、フィードの「Refresh」を押します。
Q. 記事が抜粋しか出ない
フィードの編集画面で「Fetch original content」を有効にすると、元ページから全文を取りに行きます。
それでも崩れる場合は「Scraper Rules」で本文の範囲を指定します。
Q. Google NewsのRSSで、関係ないニュースも混ざる
キーワードが広すぎると、関係ない記事も拾います。
キーワードを具体的にしたり、複数の言葉を組み合わせたりすると、ほしいニュースに近づきます。
Q. 大手サイトのニュースだけ取り込めない
本文で触れたように、Bot対策が入っているサイトは直接の取得がはじかれることがあります。
その場合は、サイトを直接読むのをあきらめて、Google News経由(キーワードにサイト名やテーマを入れる)に切り替えるのが現実的です。
まとめ
いかがでしたか。
今回は、RSSリーダーを自前のMinifluxで立て、さらにGoogle Newsまで取り込む方法を紹介しました。
振り返ると、
- Minifluxは軽量で無料の、本体(
miniflux/miniflux)+データベース(postgres:17)で動く自分専用のRSSリーダー - ポートは8750、更新間隔は10分(
POLLING_FREQUENCY=10)など、構成ファイルの値で動きを決める - 最初の管理者は
miniflux -create-adminで作り、フィードはURLを貼るだけで登録できる - RSSの無いサイトはRSSHub+Redisで、キーワード追跡はGoogle NewsのRSSで取り込む
- 大手サイトのBot対策は、Google Newsを一段かませて回避する(自作のnews-scraper経由)
- 抜粋しか出ないフィードは「Fetch original content」で全文取得し、外から読むときはTailscale経由でアクセスする
という内容でした。
自分が選んだ情報源だけが、雑音なしで並ぶRSSリーダーは、想像以上に快適です。
広告やおすすめに時間を奪われず、自分の意思で情報を選べるのがいちばんの利点だと思います。
なお、同じサーバーの上でObsidianを外部から操作できるようにしたMCPサーバーの話は、別の記事にまとめています。
この記事が誰かの役に立てばうれしいです。