クイックスタート:5分でFreshRSSを起動する
自分専用のRSSリーダーを持つことは、ホームラボの小さな勝利のひとつで、毎日の生活をじわじわ改善してくれる。FreshRSSをセルフホストして2年以上になるが、もしなくなったら最も惜しいサービスだと思う。アルゴリズムなし、広告なし、フィードの制限なし――購読したコンテンツが公開されたらそのまま届くだけだ。
FreshRSSを最速で動かす手順はこちら:
mkdir -p ~/freshrss/{data,extensions}
docker run -d \
--name freshrss \
-p 8080:80 \
-e TZ=Asia/Tokyo \
-e CRON_MIN='*/15' \
-v ~/freshrss/data:/var/www/FreshRSS/data \
-v ~/freshrss/extensions:/var/www/FreshRSS/extensions \
--restart unless-stopped \
freshrss/freshrss:latest
http://<サーバーのIPアドレス>:8080 を開くとセットアップウィザードが表示される。データベースを選択し(個人利用ならSQLiteで十分)、管理者アカウントを作成すれば完了だ。
始めるにはこのコマンド1つで十分。ただし、本番環境レベルにしたい――データを永続化し、リバースプロキシを立て、全デバイスで同期させたい――なら読み続けてほしい。
詳細解説:PostgreSQLを使ったDocker Composeの設定
SQLiteは個人利用には問題ないが、フィードが数百件を超えたりマルチユーザー対応が必要になった場合は、PostgreSQLの方が賢い選択だ。実際に使いながら磨き上げたComposeファイルを紹介する:
version: '3.8'
services:
freshrss:
image: freshrss/freshrss:latest
container_name: freshrss
restart: unless-stopped
ports:
- '8080:80'
environment:
TZ: Asia/Tokyo
CRON_MIN: '*/15'
FRESHRSS_ENV: production
volumes:
- ./data:/var/www/FreshRSS/data
- ./extensions:/var/www/FreshRSS/extensions
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
container_name: freshrss-db
restart: unless-stopped
environment:
POSTGRES_DB: freshrss
POSTGRES_USER: freshrss
POSTGRES_PASSWORD: your_strong_password_here
volumes:
- ./db:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U freshrss']
interval: 10s
timeout: 5s
retries: 5
docker compose up -d
セットアップウィザードではデータベースの種類にPostgreSQLを選択し、Composeファイルに合わせた認証情報を入力する。FreshRSSは初回起動時に自動でスキーマを作成するため、追加作業は不要だ。
リバースプロキシの背後に置く
ポート8080はテスト用には十分だが、LANの外からFreshRSSにアクセスする場合はHTTPSが必要になる。Nginx Proxy ManagerやTraefikがすでにホームラボで動いているなら、rss.yourdomain.com のようなサブドメインをDockerホストのポート8080に向ければいい。
Nginx Proxy Managerなら数クリックで完了する。プロキシホストを追加し、転送先ホスト名にDockerホストのIPアドレスとポート8080を設定し、Let’s EncryptでSSLを有効化してHTTPSを強制するだけ。2分かからない。
Traefikユーザーは代わりにfreshrssサービスへ以下のラベルを追加しよう:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.freshrss.rule=Host(`rss.yourdomain.com`)'
- 'traefik.http.routers.freshrss.entrypoints=websecure'
- 'traefik.http.routers.freshrss.tls.certresolver=letsencrypt'
- 'traefik.http.services.freshrss.loadbalancer.server.port=80'
フィード更新間隔の設定
CRON_MIN変数はFreshRSSがフィードをポーリングする頻度を制御する。*/15は15分ごとを意味し、鮮度とサーバー負荷のバランスとして妥当な設定だ。リソースが限られたVPSでは*/30に変更しても、実用上はほとんど差を感じない。
管理 → アーカイブから手動で更新をトリガーすることも、CLIから直接実行することもできる:
docker exec -it freshrss php /var/www/FreshRSS/app/actualize_script.php
APIアクセスとモバイル同期
多くのセルフホストRSSツールはウェブアクセスで止まっている。FreshRSSはそこからさらに踏み込み、Google Reader APIを実装している(さらに拡張機能経由でFever APIにも対応)。Google ReaderバックエンドをサポートするほぼすべてのRSSクライアントと互換性があり、これは驚くほど大きなエコシステムだ。
APIを有効化する
ユーザー設定 → プロフィールに移動し、APIパスワードを設定する。ログインパスワードと同じでも構わないが、別のパスワードを設定する方がすっきりする。次に管理 → 認証に移動し、APIアクセスを許可するにチェックを入れる。
APIエンドポイントは以下のようになる:
https://rss.yourdomain.com/api/greader.php
モバイルクライアントの設定
私の日常環境はiOSでNetNewsWire、macOSでReeder 5――どちらもGoogle Reader APIをネイティブサポートしている。FreshRSSのURLにユーザー名とAPIパスワードを設定するだけで、WiFiでもLTEでもほぼリアルタイムで同期される。
AndroidではFeedMeとRead You(完全オープンソース)が同じエンドポイントで問題なく動作する。
既存のフィードをインポートする
Feedly、Inoreader、その他サービスからの移行は?購読リストをOPMLとしてエクスポートし、購読管理 → インポート/エクスポートからインポートすればいい。FeeldyからOPMLを読み込んで340件のフィードを8秒ほどでインポートできた――FreshRSSは微塵も動じなかった。
バックアップを自動化する
フィード、既読状態、設定、ユーザーデータはすべて./dataに保存される。シンプルな夜間スクリプトで十分だ:
#!/bin/bash
BACKUP_DIR="/mnt/nas/backups/freshrss"
DATE=$(date +%Y%m%d)
tar -czf "${BACKUP_DIR}/freshrss-${DATE}.tar.gz" ~/freshrss/data ~/freshrss/db
find "${BACKUP_DIR}" -name '*.tar.gz' -mtime +30 -delete
cron(crontab -e)に追加して午前3時に実行するよう設定する:
0 3 * * * /home/user/scripts/backup-freshrss.sh
毎日使って分かった実践的なコツ
2年間実際に運用して学んだこと――これを知らないと私と同じ壁にぶつかるはずだ。
1. フィード数に気を配る
FreshRSSは低スペックのハードウェアでも数百件のフィードを処理できる。1コア・1GB RAMのVPSで文句なく動く。本当のボトルネックは更新頻度の高いソースで、ニュースサイトによっては1日50件以上の記事を配信するものもある。購読管理でフィードごとの保存件数に上限を設けよう。私はほとんどのフィードを200件に設定し、一部の重要なものだけ無制限にしている。これでデータベースをスリムに保てる。
2. ラベル機能は過小評価されている
多くの人がFreshRSSのラベル機能を無視している。それはもったいない。後で読む、DevOps、ニュースレターといったラベルを作り、フィードのソースやタイトルのキーワードに基づいて自動割り当てするフィルタリングルールを設定しよう。FreshRSSが単なるパッシブなリーダーから、軽量なコンテンツキュレーションレイヤーに変わる――サードパーティのツール不要で。
3. 共有連携機能を活用する
ユーザー設定 → 共有から、Pocket、Wallabag、任意のカスタムURLへのワンクリック保存を設定できる。私はセルフホストのWallabagインスタンスに向けている。長文記事はクリック1つで保存でき、タブを行き来する必要がない。
4. フィード取得の問題をデバッグする
フィードが更新されなくなったら、購読管理でそのフィードの状態を確認しよう――エラーのあるフィードはそこにフラグが立つ。9割以上はRSS URLの変更、サイトのダウン、または認証が必要になったフィードが原因だ。コンテナ内から直接URLをテストしてみよう:
docker exec -it freshrss curl -I 'https://example.com/feed.xml'
5. メモリ使用量のチューニング
メモリが少ないVPSでは、リソース制限を追加して過剰使用を防ごう:
services:
freshrss:
# ... その他の設定
deploy:
resources:
limits:
memory: 256M
SQLiteを使ったFreshRSSは通常時100MB未満で動作する。PostgreSQLを加えると多少オーバーヘッドが増えるが、個人利用なら256MBを大幅に下回るはずだ。
6. 入れる価値のある拡張機能
./extensionsボリュームが存在する理由がある。実際に毎日使っている3つを紹介する:
- xExtension-CustomCSS — コアファイルに触れずにUIを調整できる
- cn-metrics — 中国語の技術系フィードをフォローしている場合に便利
- Fever API拡張機能 — ReederのFeverプロトコル互換を有効化する
拡張機能を~/freshrss/extensions/に配置し、管理 → 拡張機能から有効化しよう。
7. イメージを最新の状態に保つ
FreshRSSは定期的にアップデートをリリースしている。Docker Composeでのアップグレード手順はコマンド2つだけ:
docker compose pull
docker compose up -d
データベースのマイグレーションは起動時に自動で実行される。それでも、メジャーバージョンをまたぐ場合は事前にバックアップを取っておこう。30秒で完了するし、何か問題が起きたときに必ず役に立つ。
FreshRSSを毎日2年以上運用してきて、今やほとんど意識しないインフラになった――これはセルフホストサービスに贈れる最高の賛辞だと思う。軽量で、APIサポートが充実していて、試したモバイルクライアントすべてと互換性がある。ホームラボを構築しているなら、自分でコントロールできるRSSリーダーは持つ価値がある。FreshRSSは迷わず勧められる一択だ。

