RSS lets you follow websites, blogs, YouTube channels, podcasts and release feeds chronologically, without algorithms. FreshRSS is a polished, self-hosted RSS aggregator: a fast web interface, multiple users, filters and labels, extensions, and APIs that let popular mobile apps sync your feeds and read status. It runs well on the smallest VPS.

A lighter, minimalist alternative: Miniflux.

Install with Docker

# /opt/freshrss/compose.yaml
services:
  freshrss:
    image: freshrss/freshrss:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    environment:
      TZ: Etc/UTC
      CRON_MIN: "*/20"          # refresh feeds every 20 minutes
    volumes:
      - ./data:/var/www/FreshRSS/data
      - ./extensions:/var/www/FreshRSS/extensions
cd /opt/freshrss && docker compose up -d

Open the web installer and choose the database: SQLite is perfect for personal use, and PostgreSQL or MySQL suit larger multi-user instances. Then create the admin account.

Or on an existing LEMP server

Download the release into /var/www/freshrss, point Nginx’s root at its p/ subfolder (the only public directory), and set up PHP-FPM. Then add a cron job for refreshes:

*/20 * * * * www-data php /var/www/freshrss/app/actualize_script.php > /tmp/freshrss.log 2>&1

See Nginx with PHP-FPM and crontab.

HTTPS with Nginx

server {
    server_name rss.example.com;
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port $server_port;
    }
    # listen 443 ssl; certbot --nginx -d rss.example.com
}

Set Base URL in FreshRSS’s settings to https://rss.example.com. See Let’s Encrypt.

Add feeds

  • Add feeds by URL. FreshRSS discovers the feed from a site’s homepage in most cases.
  • Import OPML from another reader (Settings → Import/export).
  • Organise feeds into categories, and use filters (mark as read, or label, by keyword or author) and favourites.
  • Many sites without RSS can be followed through RSS-Bridge, or the built-in “web scraping” feed type (XPath).

Useful feed sources: YouTube channels (https://www.youtube.com/feeds/videos.xml?channel_id=…), GitHub releases (https://github.com/OWNER/REPO/releases.atom), subreddits (/r/name/.rss) and podcasts.

Mobile and desktop apps via the API

Enable the API in Settings → Profile → API management, and set an API password. Then use:

  • Google Reader API clients: Reeder, NetNewsWire, FeedMe, Read You, FocusReader and others, with the URL https://rss.example.com/api/greader.php;
  • Fever API clients: https://rss.example.com/api/fever.php.

Read status syncs across all devices.

Extensions and multi-user

  • Extensions (Settings → Extensions) add features such as YouTube embeds, reading time and custom CSS. Drop extra ones into ./extensions.
  • Multi-user: admins create users, each with their own feeds. Disable open registration for private instances.

Resources

FreshRSS is light. A small VPS handles thousands of feeds for several users. Feed refreshes generate brief bursts of outbound requests and some CPU, and the database grows with stored articles. Configure archiving (keep N articles or N months per feed) to control size.

Backups and updates

  • Back up ./data (config, users and the SQLite database or a DB dump). See backup strategy.
  • Export OPML occasionally as a portable copy of your subscriptions.
  • Update: docker compose pull && docker compose up -d. See updating self-hosted apps.

Quick reference

Task Setting / path
Refresh interval CRON_MIN (Docker), or cron actualize_script.php
Google Reader API /api/greader.php
Fever API /api/fever.php
Data ./data volume
Import / export OPML in Settings

Related: Miniflux and Wallabag read-it-later.

  • Self-Hosting
  • RSS
  • Docker