How to Install FreshRSS (Your Own News Reader, No Algorithm)

Social feeds show you what keeps you scrolling. An RSS reader shows you what you chose, in order, and then it's done. FreshRSS is a fast, self-hosted reader: add a site's feed and new posts appear; YouTube channels, subreddits, newsletters and podcasts all work; a phone app syncs read state; and there's a trick for sites that don't offer a feed at all.
Quick reference
| Task | What |
|---|---|
| Folder | ~/docker/freshrss/compose.yaml |
| Web | http://server-ip:8080 |
| Add a feed | + Subscription management → Add a feed → paste the site URL |
| Phone apps | FeedMe, Readrops (Android); Reeder, NetNewsWire, Fiery Feeds (iOS) via the Google Reader API |
| Refresh | automatic every 20 min (CRON_MIN), or the refresh button |
| Sites without feeds | XPath or HTML + XPath feed type |
1. The compose file
mkdir -p ~/docker/freshrss && cd ~/docker/freshrss
nano compose.yaml
services:
freshrss:
image: freshrss/freshrss:latest
container_name: freshrss
ports:
- "8080:80"
environment:
TZ: Europe/London
CRON_MIN: "*/20"
volumes:
- ./data:/var/www/FreshRSS/data
- ./extensions:/var/www/FreshRSS/extensions
restart: unless-stopped
CRON_MIN refreshes feeds every 20 minutes inside the container — no cron on the host needed.
docker compose up -d
sudo ufw allow 8080/tcp
Open http://192.168.1.50:8080, choose a language, pick SQLite for the database (plenty for one household), create your user. Done.
2. Add feeds
Subscription management → Add a feed. Paste a site's address — FreshRSS finds the feed itself in most cases. Put it in a category (News, Tech, Friends, Video).
Where feeds hide:
- YouTube channel: https://www.youtube.com/feeds/videos.xml?channel_id=UC... (the channel ID is in the page source, or paste the channel URL and let FreshRSS work it out).
- Subreddit: https://www.reddit.com/r/homelab/.rss
- GitHub releases: https://github.com/owner/repo/releases.atom
- Newsletters: a Kill-the-Newsletter address turns emails into a feed.
- Podcasts: the show's RSS link (every podcast has one).
Import an OPML file from a previous reader with Import / export.
3. Sites with no feed
Add the feed with Type: HTML + XPath. Give it the page URL and an XPath for each item, such as //article for items and .//h2 for the title. The first one takes some fiddling with the browser's inspector; afterwards you'll do it in two minutes. This is how you follow a council page, a local shop's news, or anything that still updates a plain HTML page.
4. On your phone
Settings → Authentication → Allow API access, and set an API password in your profile. Then in the app, choose FreshRSS or Google Reader API, server http://192.168.1.50:8080/api/greader.php (or the https proxy address), your username and the API password. Read state syncs both ways.
5. Keep it tidy
- Settings → Archiving: keep 50 articles per feed and anything starred; purge the rest. The database stays small.
- Labels for "read later" and "share with Sarah".
- Keyboard: j/k next/previous, m mark read, s star, v open the original.
- Sharing: every article has a share menu — to Wallabag, Mastodon, email, or a Linkding bookmark (tutorial 113).
Behind the proxy
rss.example.com → 127.0.0.1:8080 (tutorial 28), and set base_url in ./data/config.php to the https address if the app has trouble.
Troubleshooting
Feed says "invalid" when added. The site blocks bots. Edit feed → Advanced → User-Agent to a browser string usually fixes it.
Articles never update. docker compose logs freshrss — look for cron. Or the feed's site has rate-limited you; set a longer refresh for that feed.
App can't log in. API access not enabled, or you used the normal password instead of the API password.
YouTube feed shows no videos. Wrong channel ID (it starts with UC, not @handle).
Wrapping up
One container, SQLite, add feeds by pasting URLs, API on for the phone. You read what you chose, in order, and when the list is empty you're finished — a feeling no algorithm will ever give you.
