Skip to content
Serverküche
Search

Loading search … (only available on the published site).

Applications Difficulty: Intermediate

FreshRSS: Your Own RSS Reader

All your news sources in one place, no algorithm and no tracking: FreshRSS as a self-hosted RSS reader behind Traefik – with mobile app sync and backup.

· 5 min read ·Duration: approx. 40 minutes
Table of contents

RSS is the best news format most people have forgotten: you subscribe to sources directly, with no algorithm, no ads and no one watching what you read. FreshRSS gathers all your sources in one self-hosted place – and even syncs with the RSS apps on your phone.

What are we building?

Your own RSS reader with FreshRSS (v1.29.1) behind Traefik, collecting your news sources and keeping them fresh via cron in the background. By the end you read tech news, blogs, YouTube channels and podcasts in one place, grouped into categories – and can connect mobile apps like Reeder or FeedMe via the built-in Google Reader API. FreshRSS is refreshingly lightweight: SQLite is enough, no separate database needed.

Prerequisites

🍳 Recommendation Ad

VPS 1000 G12

4 vCores · 8 GB RAM · 256 GB NVMe

from €10.36/month

FreshRSS is frugal – the smallest VPS handles many feeds.

Go to netcup →

💶 5 € voucher for new netcup customers:36nc17844976032 (new customers only, no domains)

Step by step

Step 1: Create the Compose file

FreshRSS keeps everything in a data directory (SQLite database, config, cache). Create the project:

Terminal
mkdir -p /opt/freshrss && cd /opt/freshrss

The compose.yaml – replace YOUR_DOMAIN:

YAML
services:
  freshrss:
    image: freshrss/freshrss:1.29.1
    restart: unless-stopped
    volumes:
      - ./data:/var/www/FreshRSS/data
      - ./extensions:/var/www/FreshRSS/extensions
    environment:
      TZ: Europe/Berlin
      CRON_MIN: '13,43'
    networks: [proxy]
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.freshrss.rule=Host(`YOUR_DOMAIN`)"
      - "traefik.http.routers.freshrss.entrypoints=websecure"
      - "traefik.http.routers.freshrss.tls.certresolver=le"
      - "traefik.http.services.freshrss.loadbalancer.server.port=80"

networks:
  proxy:
    external: true

CRON_MIN is a nice touch of the official image: it starts an internal cron that refreshes the feeds automatically at the given minutes (here 13 and 43 of every hour) – you need no external timer.

Step 2: Start

Terminal
docker compose up -d

Check that FreshRSS responds with valid HTTPS (the 302 is the redirect to the install wizard):

Terminal
curl -sI https://YOUR_DOMAIN/ | head -1
Ausgabe
HTTP/2 302

Step 3: The install wizard

Open https://YOUR_DOMAIN/ in the browser. The wizard walks you through setup in five steps – language, system check, database, account:

The FreshRSS install wizard, step 1: language selection with version 1.29.1
The install wizard guides you through language, system check, database and admin account

Choose SQLite as the database type (no further details needed), form-based authentication and create your administrator account with a strong password. After the last step you’re logged in.

Alternative: setup from the command line

To script the initial setup without a browser: docker compose exec -u www-data freshrss ./cli/do-install.php --default-user admin --auth-type form --db-type sqlite --language en, then ./cli/create-user.php --user admin --password 'YOUR_PASSWORD'. Handy for reproducible setups – for getting started the graphical wizard is more convenient.

Step 4: Subscribe to your first feeds

Click Subscription management → Add a feed or category at the top left. Enter a source’s feed URL (e.g. https://www.heise.de/rss/heise-atom.xml) and assign it to a category. FreshRSS detects the feed format automatically. After adding several sources the management view looks like this:

The FreshRSS subscription management with feeds in the News and Uncategorized categories
Subscription management: feeds grouped into categories, with import/export and statistics

Bring existing feeds via OPML

Switching from another reader (Feedly, Inoreader, old Google Reader)? Export an OPML file there and import it under “Import / Export”. All your subscriptions move over in one click – including the category structure.

Step 5: Reading

Back in the reading view, FreshRSS collects articles from all sources chronologically, grouped by category. Unread counters per feed, stars for favorites, full-text search – it’s all there:

The FreshRSS reading view with recent articles from heise online and t3n, grouped in categories
The reading view: all sources in one place, with unread counters and search

Step 6: Connect mobile apps (optional)

FreshRSS speaks the Google Reader API, so many mobile apps can use it as a sync backend. Enable it under Settings → Profile → External access via API and set a separate API password there. In the app (e.g. Reeder, FeedMe, NetNewsWire) choose “FreshRSS” or “Google Reader API”, enter https://YOUR_DOMAIN/api/greader.php, your username and the API password – and keep reading in sync on the go.

When things go wrong

The wizard reports write-permission errors on the data folder. The container runs as www-data (UID 33). With a bind-mounted ./data the permissions must match: chown -R 33:33 /opt/freshrss/data (see Users & permissions).

Feeds don’t refresh automatically. Check whether CRON_MIN is set and the internal cron is running: docker compose logs freshrss | grep -i cron. You can trigger a refresh anytime with the refresh button at the top right or docker compose exec -u www-data freshrss ./cli/actualize-user.php --user admin.

A feed stays empty / is marked “inactive”. The source doesn’t serve valid RSS/Atom, or the URL is an HTML page instead of the feed. Many sites hide the feed – search the page source for application/rss+xml. Under “Statistics → Inactive feeds” you’ll find problem sources gathered.

Login fails even though the password is correct. FreshRSS encrypts the password in the browser (JavaScript). If JavaScript is disabled or the connection isn’t really HTTPS (certificate warning), the login fails. Via Traefik HTTPS is guaranteed – check the certificate if in doubt.

Articles are missing after an update. FreshRSS purges old articles after a configurable period (default: a few weeks). That’s intentional and keeps the database small; raise the retention per feed in its settings if needed.

Maintenance & backups

  • Updates. Occasionally bump the image tag (freshrss/freshrss:1.29.1) to the new version and docker compose up -d; FreshRSS migrates its database automatically at start. The project announces larger jumps in the release notes – usually there’s nothing else to do. Your normal update process handles the rest.
  • Backup. The entire state lives in the data folder (SQLite database + config). Add it to your Restic backup – then subscriptions, categories and read markers are safe. Additionally a regular OPML export of your feed list makes a human-readable, reader-independent backup.
  • Low effort. FreshRSS is a “set it up once, then it just runs” service. The only recurring task is curating your feed list – prune dead sources under “Inactive feeds”, subscribe to new ones.

Last updated: Sep 9, 2026

You might also like