How to Self-Host FreshRSS with Docker Compose
What Is FreshRSS?
FreshRSS is a self-hosted RSS and Atom feed aggregator. It replaces services like Feedly, Inoreader, and NewsBlur with something you fully control. FreshRSS supports multiple users, full-text search, feed categorization, the Google Reader API (for mobile app sync), WebSub for real-time updates, and extensions for additional functionality. It’s lightweight, fast, and handles thousands of feeds without breaking a sweat.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 512 MB of free RAM (minimum)
- 1 GB of free disk space
- A domain name (optional, for remote access)
Docker Compose Configuration
Create a docker-compose.yml file:
services:
freshrss:
image: freshrss/freshrss:1.28.1
container_name: freshrss
restart: unless-stopped
ports:
- "8080:80"
environment:
TZ: "America/New_York" # Your timezone
CRON_MIN: "1,31" # Feed refresh schedule (minutes past the hour)
volumes:
- freshrss_data:/var/www/FreshRSS/data
- freshrss_extensions:/var/www/FreshRSS/extensions
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
volumes:
freshrss_data:
freshrss_extensions:
FreshRSS uses SQLite by default, which works well for single-user or small multi-user setups. For larger deployments, use PostgreSQL:
services:
freshrss:
image: freshrss/freshrss:1.28.1
container_name: freshrss
restart: unless-stopped
ports:
- "8080:80"
environment:
TZ: "America/New_York"
CRON_MIN: "1,31"
volumes:
- freshrss_data:/var/www/FreshRSS/data
- freshrss_extensions:/var/www/FreshRSS/extensions
depends_on:
freshrss_db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
freshrss_db:
image: postgres:16-alpine
container_name: freshrss_db
restart: unless-stopped
environment:
POSTGRES_USER: freshrss
POSTGRES_PASSWORD: change_this_strong_password # CHANGE THIS
POSTGRES_DB: freshrss
volumes:
- freshrss_db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U freshrss"]
interval: 10s
timeout: 5s
retries: 5
volumes:
freshrss_data:
freshrss_extensions:
freshrss_db:
Start the stack:
docker compose up -d
Initial Setup
- Open
http://your-server-ip:8080in your browser - FreshRSS walks you through a setup wizard:
- Language: Select your preferred language
- Database: Choose SQLite (simple) or PostgreSQL (if you configured it above — host:
freshrss_db, port:5432, user:freshrss, password: your password, database:freshrss) - Admin account: Create your admin username and password
- After setup, log in and start adding feeds
Configuration
Feed Refresh Schedule
The CRON_MIN environment variable controls when feeds are refreshed. Examples:
"1,31"— refresh at :01 and :31 past every hour (default)"*/15"— refresh every 15 minutes"2,32"— offset by a minute to reduce load spikes
API Access (Mobile Apps)
FreshRSS supports the Google Reader API and Fever API for mobile app sync:
- Go to Settings → Authentication
- Check Allow API access
- Set an API password (separate from your login password)
- Mobile apps that work with FreshRSS:
- Android: FeedMe, Readrops, EasyRSS
- iOS: NetNewsWire, Reeder, lire
API endpoint: https://your-domain/api/greader.php
Extensions
FreshRSS has a built-in extension system. Install extensions by placing them in the extensions volume:
docker compose exec freshrss sh -c "cd /var/www/FreshRSS/extensions && \
git clone https://github.com/FreshRSS/Extensions.git"
Enable extensions under Settings → Extensions.
Advanced Configuration (Optional)
WebSub (Real-Time Updates)
FreshRSS supports WebSub (formerly PubSubHubbub) for instant feed updates instead of polling:
- Go to Settings → System configuration
- Set Base URL to your public-facing URL
- Enable WebSub — feeds that support it push updates to FreshRSS in real time
Full-Text Retrieval
FreshRSS can fetch full article content from truncated feeds using XPath or CSS selectors per feed, or using the Full-Text RSS extension.
LDAP Authentication
For team deployments, FreshRSS supports LDAP via the HTTP_AUTH method and an external reverse proxy doing LDAP authentication.
Reverse Proxy
FreshRSS works behind any reverse proxy. Set the Base URL in FreshRSS settings to match your domain.
Example Nginx Proxy Manager config:
- Scheme: http
- Forward Hostname: freshrss (container name)
- Forward Port: 80
- Enable WebSocket Support: Yes (for real-time features)
See Reverse Proxy Setup for full configuration.
Backup
Back up the freshrss_data volume — it contains your configuration, user data, and SQLite database (if using SQLite). If using PostgreSQL, also back up the freshrss_db volume or use pg_dump.
# SQLite setup
docker run --rm -v freshrss_data:/data -v $(pwd):/backup alpine \
tar czf /backup/freshrss-backup-$(date +%Y%m%d).tar.gz /data
# PostgreSQL
docker compose exec freshrss_db pg_dump -U freshrss freshrss > freshrss-backup.sql
See Backup Strategy for a complete backup approach.
Troubleshooting
Feeds Not Updating
Symptom: Feeds show stale content, no new articles appearing.
Fix: Check that CRON_MIN is set correctly in your environment variables. Verify the cron is running:
docker compose exec freshrss cat /var/log/cron.log
If cron isn’t running, restart the container. FreshRSS starts cron automatically on container start.
API Returns 403 Forbidden
Symptom: Mobile apps can’t connect, API returns 403.
Fix: Enable API access in Settings → Authentication and set a separate API password. Make sure your reverse proxy passes the Authorization header.
High Memory Usage with Many Feeds
Symptom: Container using excessive RAM with 500+ feeds. Fix: Reduce the number of articles retained per feed in Settings → Reading → Article retention. Switch from SQLite to PostgreSQL for better performance with large datasets.
Cannot Log In After Update
Symptom: Login fails after upgrading FreshRSS version. Fix: Clear the browser cache or try incognito mode. If persistent, run the database migration manually:
docker compose exec freshrss php ./cli/reconfigure.php
Resource Requirements
- RAM: ~50 MB idle, ~150 MB during feed refresh with 200+ feeds
- CPU: Very low — negligible except during feed refresh
- Disk: ~100 MB for the application, plus storage for cached articles (varies by retention settings)
Verdict
FreshRSS is the best self-hosted RSS reader for most people. It’s lightweight, feature-rich, supports mobile app sync via Google Reader API, and handles thousands of feeds reliably. If you want a single-binary, minimalist alternative, look at Miniflux. But for most users, FreshRSS hits the sweet spot of features, performance, and ease of setup.
Frequently Asked Questions
What mobile apps work with FreshRSS?
FreshRSS supports the Google Reader API and Fever API, which enables sync with many mobile RSS readers. Best options: NetNewsWire (iOS/Mac, free), Reeder (iOS, $5), FeedMe (Android, free), ReadYou (Android, free and open-source). Enable the API in FreshRSS settings, create an API password, and configure the mobile app to use your FreshRSS URL as the server endpoint.
How often does FreshRSS check for new articles?
By default, FreshRSS refreshes feeds when you open the web UI or when triggered by a cron job. For automatic background updates, set up a cron job that hits the FreshRSS actualize endpoint every 15-30 minutes. The Docker image includes a built-in cron service if you set CRON_MIN (e.g., CRON_MIN=*/15 for every 15 minutes). Each feed can also have individual refresh intervals configured in its settings.
Can FreshRSS handle full-text extraction for truncated feeds?
Yes, using the XPath Scraping extension or the Full-Text RSS extension. Many feeds only provide article summaries. FreshRSS can fetch the full article content from the original website and display it inline. Configure XPath selectors per feed to target the article content element. This is one of FreshRSS’s strongest features compared to commercial readers.
How much storage does FreshRSS need?
Very little. FreshRSS with 200-500 feeds and 90-day article retention typically uses 500 MB-1 GB of database storage. RAM usage is around 50-100 MB. The main growth factor is how many feeds you subscribe to and how long you keep articles. Configure article retention under Settings > Archiving — 90 days is a reasonable default. Starred/favorited articles are kept regardless of retention settings.
Can multiple users share one FreshRSS instance?
Yes. FreshRSS supports multiple accounts with independent feed subscriptions, read/unread states, favorites, and settings. Each user manages their own feeds. The admin user can set registration to open or invite-only. User management is accessed from Administration > Manage users.
How does FreshRSS compare to Miniflux?
FreshRSS is more feature-rich: it has extensions, XPath scraping, multiple view modes (normal, global, reader), better feed management, and more theming options. Miniflux is more minimalist: a single Go binary with a clean UI, faster performance, and simpler maintenance. Choose FreshRSS if you want customization and power features. Choose Miniflux if you want simplicity and speed. Both support the same mobile app ecosystem via API compatibility.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments