Take Back Control of Your News Feed
RSS never died – it just got buried under algorithmic feeds, paywalls, and platform lock-in. For anyone who wants to read content on their own terms, a self-hosted RSS reader cuts through all of that. Miniflux is a particularly clean solution: a Go-based RSS aggregator that runs as a single binary, exposes a minimal web UI, and stores everything in a PostgreSQL database. No plugins, no bloat, no tracking.
What makes Miniflux worth the setup effort is its design philosophy. It does one thing – aggregate and display feeds – and it does that without the cruft that makes tools like FreshRSS or Tiny Tiny RSS feel heavy. The admin interface doubles as the reading interface, the API is well-documented, and the whole stack can run on a low-spec VPS or a Raspberry Pi without breaking a sweat.

What You Need Before You Start
Miniflux runs on Linux, and the recommended deployment method is Docker Compose alongside a PostgreSQL container. You will need a server with Docker and Docker Compose installed – a 1GB RAM VPS is more than sufficient. If you want to access Miniflux from outside your local network, you will also need a domain name and a reverse proxy like Nginx or Caddy to handle HTTPS termination. Without TLS, credentials travel in plain text, which defeats the purpose of a private reader.
Before touching any config files, decide where you want Miniflux to live. A subdomain like rss.yourdomain.com keeps things tidy and separates it from other self-hosted services. Point that subdomain’s DNS A record to your server’s IP address, and let it propagate before you attempt any SSL certificate requests. This one step saves a lot of troubleshooting later.
Setting Up With Docker Compose
Create a working directory – something like /opt/miniflux – and place a docker-compose.yml file inside it. The minimal configuration needs two services: the Miniflux app container and a PostgreSQL container. Set the DATABASE_URL environment variable to point at your Postgres instance, and set RUN_MIGRATIONS=1 so Miniflux automatically creates its schema on first boot. You also need to pass CREATE_ADMIN=1, ADMIN_USERNAME, and ADMIN_PASSWORD for the initial admin account – these environment variables only take effect once, then Miniflux ignores them.
A complete working Compose file looks like this. Define a miniflux service using the miniflux/miniflux:latest image, and a db service using postgres:15. Map port 8080 on the Miniflux container to your localhost, use a named volume for Postgres data persistence, and set depends_on so the app waits for the database. Run docker compose up -d and watch the logs with docker compose logs -f miniflux to confirm the database migration succeeded. Once you see the “Starting Miniflux daemon” line, the service is ready.
With Miniflux running on port 8080, put Caddy or Nginx in front of it. Caddy is the faster path – its Caddyfile needs just three lines: the subdomain, a reverse_proxy localhost:8080 directive, and nothing else, because Caddy handles certificate provisioning automatically via Let’s Encrypt. Nginx requires a slightly longer config block and a separate Certbot run, but both approaches produce the same result: Miniflux accessible over HTTPS with a valid certificate.

Configuring Feeds, Filters, and the Reading Experience
Once you log in, the first order of business is adding feeds. Miniflux accepts RSS, Atom, and JSON Feed URLs. Paste a feed URL into the Add Feed dialog and Miniflux fetches it immediately, pulling in whatever historical items the feed exposes. For most feeds that means the last 10 to 20 entries. From that same dialog you can set a per-feed refresh interval, override the scraping behavior, and assign the feed to a category. Categories are the primary organizational unit in Miniflux – create them before importing a large OPML file to avoid sorting chaos afterward.
The scraper feature deserves specific attention. Many sites publish truncated feed items – a headline and two sentences – and expect you to click through to the full article. Miniflux has a built-in content scraper that fetches the original page and extracts the main article body using a set of CSS rules. Enable it per-feed with the Fetch original content toggle. For sites where the automatic scraper produces poor results, Miniflux supports custom scraper rules written as CSS selectors stored in its scraperRules configuration. This gets you full articles inside the reader without ever opening a browser tab.
The reading interface keeps things keyboard-first. j and k move between entries, v opens the original URL, b saves to a bookmarking integration, and m toggles read status. Miniflux supports a range of third-party integrations out of the box: Pinboard, Wallabag, Pocket, Instapaper, Readwise, Notion, and several others. Each integration is configured from the Settings panel with an API key and, in some cases, a base URL if you are connecting to another self-hosted service. There is no extension or plugin system – integrations are baked in, which keeps the attack surface small.
For teams or households running a shared instance, Miniflux supports multiple user accounts. Each user gets their own feed list, categories, and read state – nothing is shared between accounts except the server itself. The admin user can create additional accounts from the admin panel and set per-user API rate limits. The Miniflux API follows REST conventions and returns JSON, so building a custom mobile client or automating feed management with a shell script is straightforward. Several third-party mobile apps already use it: Reeder on iOS supports Miniflux as a sync backend, and so does NetNewsWire.

Keeping It Running and Staying Updated
Miniflux updates frequently, and staying current matters because feed parsing bugs and scraper improvements ship regularly. Updating the Docker deployment is a two-command process: docker compose pull followed by docker compose up -d. Miniflux runs database migrations automatically on startup when the schema version changes, so there is no manual migration step. Back up your PostgreSQL volume before major version jumps anyway – pg_dump into a compressed file on a cron schedule is the minimum viable backup strategy.
Resource usage stays predictable. Miniflux’s refresh worker polls feeds at the configured interval using a background goroutine pool. With several hundred feeds and a 30-minute refresh cycle, CPU usage on a shared VPS stays low enough that it coexists comfortably with other services on the same host. PostgreSQL is the only component that grows meaningfully over time, as article content accumulates. Miniflux does not automatically purge old entries by default, but the cleanup_frequency_hours and archive_read_days settings control retention once you configure them.
One thing Miniflux does not do is sync your reading state to other apps the way Fever or Google Reader used to. If you switch clients mid-day, read state propagates through the API, so anything using the Miniflux API as a backend stays in sync. But there is no OPML live sync, no cross-instance federation, and no mobile push notification for new items. Those are deliberate omissions. Whether they matter depends entirely on how you read – and for anyone who treats RSS as a focused, scheduled reading habit rather than a real-time notification stream, none of those gaps will come up.
Frequently Asked Questions
Can Miniflux run on a Raspberry Pi?
Yes. Miniflux is a single Go binary with minimal resource requirements. A Raspberry Pi 3 or newer running Raspberry Pi OS handles it comfortably alongside PostgreSQL.
Does Miniflux support mobile apps?
Miniflux has a REST API that several third-party apps support, including Reeder on iOS and NetNewsWire. There is no official mobile app from the Miniflux project.
How do I keep old articles from filling up my database?
Configure the archive_read_days and cleanup_frequency_hours settings in your environment variables to automatically purge old read entries on a schedule.





