How to Self-Host FreshRSS: Feature-Rich RSS Reader 2026
TL;DR
FreshRSS (AGPL 3.0, ~9K GitHub stars, PHP) is a self-hosted RSS aggregator that supports the Google Reader API, making it compatible with every major RSS client app. It has more customization than Miniflux — themes, extensions, user management, custom CSS — while still being lightweight and easy to deploy. Feedly charges $8/month for "Pro" features. FreshRSS gives you unlimited feeds, multi-user support, and full-text fetching for free.
Key Takeaways
- FreshRSS: AGPL 3.0, ~9K stars, PHP — RSS with Google Reader API, themes, extensions
- Google Reader API: Compatible with Reeder, Readably, News+, and all GR-compatible apps
- Multi-user: Create users with different feeds and settings
- Extensions: 50+ community extensions (reading time, full-text, custom CSS, etc.)
- Stats: Track reading habits, articles per feed, unread counts
- vs Miniflux: FreshRSS is more feature-rich; Miniflux is more minimal and opinionated
Part 1: Docker Setup
# docker-compose.yml
services:
freshrss:
image: freshrss/freshrss:latest
container_name: freshrss
restart: unless-stopped
ports:
- "8080:80"
volumes:
- freshrss_data:/var/www/FreshRSS/data
- freshrss_extensions:/var/www/FreshRSS/extensions
environment:
TZ: America/Los_Angeles
CRON_MIN: "*/20" # Update feeds every 20 minutes
FRESHRSS_ENV: production
# Auto-create first user:
FRESHRSS_INSTALL: |
--api_enabled
--db-base freshrss
--db-host db
--db-user freshrss
--db-password ${DB_PASSWORD}
--db-type pgsql
--base_url https://rss.yourdomain.com
--user admin
--password ${ADMIN_PASSWORD}
--email admin@yourdomain.com
depends_on:
db:
condition: service_healthy
db:
image: postgres:15-alpine
restart: unless-stopped
environment:
POSTGRES_DB: freshrss
POSTGRES_USER: freshrss
POSTGRES_PASSWORD: "${DB_PASSWORD}"
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U freshrss"]
interval: 5s
start_period: 20s
volumes:
freshrss_data:
freshrss_extensions:
db_data:
docker compose up -d
Visit http://your-server:8080 — log in with admin / your password.
Part 2: HTTPS with Caddy
rss.yourdomain.com {
reverse_proxy localhost:8080
}
Part 3: Add Feeds
Via web UI
- + Subscribe → paste feed URL
- Or enter website URL — FreshRSS auto-detects the RSS feed
Import OPML
- Subscriptions → Import/Export → Import subscriptions
- Upload
.opmlfile from previous RSS reader
Discover feeds by website
FreshRSS can find RSS feeds from any URL:
Enter: https://arstechnica.com
→ FreshRSS finds: https://feeds.arstechnica.com/arstechnica/index
Part 4: Categories and Labels
Categories
Organize feeds into categories:
- Subscriptions → + New category
- Name:
Technology,News,Blogs,Podcasts - Assign feeds to categories
Labels
Tag individual articles:
- Article → Add label
- Labels:
to-read,interesting,work,share - Filter by label in sidebar
Part 5: Google Reader API
FreshRSS implements the Google Reader API for client app compatibility:
Enable API
- Settings → Authentication → Allow API access: Enable
- Settings → Profile → API password: Set a password (can differ from login)
API endpoint:
https://rss.yourdomain.com/api/greader.php
Compatible apps
| App | Platform | Notes |
|---|---|---|
| Reeder 5 | iOS/macOS | Best iOS RSS client, GR native |
| News+ | iOS | GR + Fever support |
| Readably | Android | Material You design |
| FeedMe | Android | Feature-rich, GR support |
| NetNewsWire | iOS/macOS | Free, open source |
| Fluent Reader | Windows/Linux/macOS | Cross-platform |
| Vienna | macOS | Classic macOS RSS client |
Reeder setup
- Reeder → + → FreshRSS
- URL:
https://rss.yourdomain.com - Username: your FreshRSS username
- Password: your API password (not login password)
Part 6: Extensions
Install extensions to add features:
# Popular FreshRSS extensions:
# Available at: https://github.com/FreshRSS/Extensions
# Install via UI:
# Settings → Extensions → + Install extension
# Upload .zip or enter GitHub URL
# Or via volume mount:
docker cp MyExtension.zip freshrss:/var/www/FreshRSS/extensions/
Notable extensions
| Extension | Function |
|---|---|
| Reading time | Shows estimated reading time per article |
| Full-text RSS | Fetches full content from truncated feeds |
| Keyboard shortcuts | Customize keyboard navigation |
| Trending | Shows trending articles across subscriptions |
| Dark theme | Solarized Dark, Gruvbox themes |
| Auto unsubscribe | Remove dead feeds automatically |
Part 7: Full-Text Fetching
For feeds with truncated content:
Using the Full-text RSS extension
1. Install the Full Text RSS extension
2. Feed settings → Use full-text RSS feed:
→ Enable for truncated feeds
Manual per-feed scraper
Feed settings → Scraper rules:
CSS selector for main content:
article, .post-content, .article-body, main .content
External full-text RSS service
# Use FiveFilters or similar:
# Original feed: https://example.com/feed/
# Full-text: https://ftr.fivefilters.org/makefulltextfeed.php?url=https://example.com/feed/&max=10
Part 8: Filtering and Rules
Keyword filters (per feed)
Feed settings → Filters:
Mark as read if: Title contains "sponsored"
Star if: Title contains "security" OR "vulnerability"
Search and filter
In the main view:
# Search across all feeds:
kubernetes → articles mentioning kubernetes
intitle:kubernetes → only in titles
author:linus torvalds → by author
date:<2026-01-01 → before date
#tag-name → by label
Maintenance
# Update:
docker compose pull
docker compose up -d
# Backup:
docker exec freshrss-db-1 pg_dump -U freshrss freshrss \
| gzip > freshrss-db-$(date +%Y%m%d).sql.gz
tar -czf freshrss-data-$(date +%Y%m%d).tar.gz \
$(docker volume inspect freshrss_freshrss_data --format '{{.Mountpoint}}')
# Force feed refresh:
docker exec freshrss php /var/www/FreshRSS/app/actualize_script.php
# Logs:
docker compose logs -f freshrss
See also: Miniflux — more minimal, keyboard-driven alternative
See all open source RSS tools at OSSAlt.com/categories/productivity.