How to Self-Host Miniflux: Minimal RSS Reader 2026
TL;DR
Miniflux (AGPL 3.0, ~6.3K GitHub stars, Go) is a deliberately minimal RSS reader — fast, opinionated, and distraction-free. No categories, no tags, no themes. What you get: all your feeds in a single sorted list, full keyboard navigation, full-text fetching, and Google Reader + Fever APIs for third-party apps. The entire server is a single Go binary + PostgreSQL. Compare Miniflux vs FreshRSS: FreshRSS is richer (extensions, multiple views, categories); Miniflux is faster and deliberately simpler — closer to the old Google Reader's "river of news" philosophy.
Key Takeaways
- Miniflux: AGPL 3.0, ~6.3K stars, Go — opinionated, minimal, keyboard-driven
- Single Go binary: No PHP, no Redis, just Go + PostgreSQL
- Full-text fetch: Retrieves full article content even for truncated feeds
- Fever + Google Reader API: Works with Reeder, NetNewsWire, Fluent Reader
- Scraper rules: Custom content extraction rules per website
- No JavaScript bloat: Server-rendered UI, loads in milliseconds
Miniflux vs FreshRSS vs Feedly
| Feature | Miniflux | FreshRSS | Feedly Pro |
|---|---|---|---|
| License | AGPL 3.0 | AGPL 3.0 | Proprietary |
| Cost | Free | Free | $8/mo |
| Language | Go | PHP | — |
| Database | PostgreSQL only | SQLite/PostgreSQL | Cloud |
| UI | Minimal, keyboard-first | Feature-rich | Rich |
| Categories | No (flat list) | Yes | Yes |
| Extensions | No | 100+ | No |
| Full-text fetch | Yes | Yes | Yes (AI) |
| Fever API | No | Yes | — |
| Google Reader API | Yes | Yes | — |
| RAM | ~30MB | ~50MB | — |
| GitHub Stars | ~6.3K | ~10K | — |
Part 1: Docker Setup
# docker-compose.yml
services:
miniflux:
image: miniflux/miniflux:latest
container_name: miniflux
restart: unless-stopped
ports:
- "8080:8080"
depends_on:
db:
condition: service_healthy
environment:
DATABASE_URL: postgres://miniflux:${POSTGRES_PASSWORD}@db/miniflux?sslmode=disable
RUN_MIGRATIONS: "1"
CREATE_ADMIN: "1"
ADMIN_USERNAME: admin
ADMIN_PASSWORD: "${ADMIN_PASSWORD}"
POLLING_FREQUENCY: 15 # Feed refresh interval (minutes)
POLLING_PARSING_ERROR_LIMIT: 3 # Disable feed after 3 errors
WORKER_POOL_SIZE: 5 # Parallel feed fetchers
BASE_URL: "https://rss.yourdomain.com"
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: miniflux
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
POSTGRES_DB: miniflux
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "miniflux"]
interval: 10s
start_period: 30s
volumes:
postgres_data:
# .env
POSTGRES_PASSWORD=your-db-password
ADMIN_PASSWORD=your-admin-password
docker compose up -d
Visit http://your-server:8080 → log in as admin.
Part 2: HTTPS with Caddy
rss.yourdomain.com {
reverse_proxy localhost:8080
}
Part 3: Import Feeds (OPML)
- Settings → Import & Export → Import Feeds → upload OPML file
- Miniflux starts fetching immediately
Export from:
- Feedly: Settings → Import & Export → Export OPML
- FreshRSS: Subscription → Import/Export → Export OPML
- NewsBlur: Account → Import/Export → Download OPML
Part 4: Keyboard Navigation
Miniflux is designed for keyboard-first use:
| Key | Action |
|---|---|
j | Next unread entry |
k | Previous entry |
m | Mark as read/unread |
v | Open original URL |
f | Toggle bookmark |
h | Show help |
g u | Go to unread |
g b | Go to starred/bookmarks |
g h | Go to history |
g f | Go to feeds list |
R | Refresh current feed |
Part 5: Full-Text Fetching
For feeds that truncate articles:
- Edit Feed → Fetch original content: Yes
- Miniflux fetches the full article from the source
Custom Scraper Rules
For sites with complex layouts, add custom CSS selectors:
# Rules are stored in miniflux's "scraper_rules" database table
# Configure via the UI: Edit Feed → Scraper Rules
# Format: CSS selector for main content
# Example for a news site:
article.article-body, div.article-content
# Or use XPath:
# xpath:article//div[@class='content']
Miniflux also supports the Readability.js algorithm as fallback.
Part 6: Connect Mobile Apps
Enable API
Miniflux supports the Google Reader-compatible API:
API endpoint: https://rss.yourdomain.com/googlereader/reader/api/0
Reeder 5 (iOS/macOS):
- Add account → Feedly (Google Reader-compatible)
- URL:
https://rss.yourdomain.com/googlereader/reader/api/0 - Username + password
NetNewsWire:
- Accounts → Add Account → Feedly
- Use Google Reader API endpoint
Fluent Reader (Windows/Linux/macOS):
- Settings → Account → Add → Miniflux
- URL:
https://rss.yourdomain.com - API key (generate in Miniflux settings)
API Key (simpler than password)
- Settings → API Keys → Create API Key
- Use in apps instead of username/password
- More secure — revocable independently
Part 7: Fever API
Miniflux doesn't support Fever natively — use FreshRSS if Fever compatibility is required (e.g., for older clients like ReadKit or Mr. Reader on iOS).
For Miniflux, the Google Reader API covers most modern clients.
Part 8: Webhooks and Integrations
Miniflux can push new articles to external services:
Integration options (Settings → Integrations):
- Apprise: Push notifications to 50+ services (Slack, Discord, Telegram, ntfy)
- Webhook: POST to any URL when new articles arrive
- Readwise: Sync highlights to Readwise
- Wallabag: Save articles directly to Wallabag
- Instapaper / Pocket: Send to read-later services
- Pinboard: Bookmark new articles
- Matrix: Post to Matrix room
- Telegram Bot: Post new articles to Telegram
Webhook setup:
// Miniflux sends POST to your URL with:
{
"event_type": "save_entry",
"feed": {
"id": 1,
"title": "Hacker News",
"feed_url": "https://news.ycombinator.com/rss"
},
"entry": {
"id": 42,
"url": "https://example.com/article",
"title": "Interesting Article",
"content": "Full article content here...",
"published_at": "2026-03-09T10:00:00Z"
}
}
Part 9: Filters
Filter entries automatically:
-
Edit Feed → Block List (regex): Hide entries matching patterns
sponsored|advertisement|promoted -
Edit Feed → Keep List (regex): Only show entries matching:
rust|golang|typescript
Rules use Go regex syntax.
Part 10: Environment Tuning
Key environment variables for optimization:
environment:
# Polling:
POLLING_FREQUENCY: 15 # Minutes between refreshes
BATCH_SIZE: 100 # Feeds fetched per batch
WORKER_POOL_SIZE: 5 # Parallel fetch workers
# Cleanup:
CLEANUP_FREQUENCY_HOURS: 24 # Run cleanup daily
CLEANUP_ARCHIVE_UNREAD_DAYS: 60 # Keep unread entries for 60 days
CLEANUP_ARCHIVE_READ_DAYS: 30 # Keep read entries for 30 days
# Security:
DISABLE_HTTP_SERVICE: "0"
CERT_FILE: "" # Let Caddy handle TLS
KEY_FILE: ""
HTTPS_ONLY: "0"
# Auth:
AUTH_PROXY_HEADER: "" # For SSO/proxy auth
Maintenance
# Update Miniflux:
docker compose pull
docker compose up -d
# Logs:
docker compose logs -f miniflux
# Backup database:
docker exec db pg_dump -U miniflux miniflux \
| gzip > miniflux-db-$(date +%Y%m%d).sql.gz
# Reset admin password:
docker exec miniflux miniflux -reset-password
# Check feeds with errors:
# Settings → Feeds → Sort by "Parsing Error" — shows feeds that need attention
See all open source news and RSS tools at OSSAlt.com/categories/productivity.