Tag: Docker

Practical guides for running self-hosted applications with Docker and Docker Compose.

  • How to Self-Host Miniflux with Docker: Compose File and the Postgres SSL Fix

    How to Self-Host Miniflux with Docker: Compose File and the Postgres SSL Fix

    Beginner · 7 min · Docker · PostgreSQL

    Tested on:

    OS Any Linux (verified on Debian 12)
    Docker 29.7
    Hardware 4-core x86, 16 GB RAM
    Software Miniflux (latest) + PostgreSQL 16

    Last tested: 22 August 2026

    Miniflux is the fastest, lightest RSS reader you can run for yourself: a single Go binary plus a database, idling at about 17 MB of RAM. This guide deploys it with Docker Compose on any Linux machine — and documents the exact error that stops most first-timers, because that is the error we hit too.

    What is Miniflux, and why it beats the alternatives

    Miniflux is a minimalist RSS reader written in Go. You point it at your feeds, and it polls, stores, and serves them in a fast interface. The account model is deliberately simple: create users, add feeds, read. No accounts, no cloud, no subscription.

    Compared to the other common self-hosted readers:

    Miniflux FreshRSS Selfoss
    Idle RAM (measured) ~17 MiB ~80–150 MiB (PHP-FPM) ~50 MiB
    Setup complexity 1 container + Postgres 1 container (PHP) + optional DB 1 container + DB
    Mobile clients Any RSS app + built-in mobile view Any RSS app Limited
    Update cadence Frequent, stable Frequent Slower

    If you want a heavy-featured reader with plugins, FreshRSS is a fine choice. For a low-maintenance daily driver, Miniflux is hard to beat.

    Prerequisites

    • A machine with Docker and the Compose plugin (docker compose version should print a version)
    • A free TCP port on your LAN (this guide uses 8082 — change it if yours is taken)

    Step 1: The compose file

    mkdir -p ~/stacks/miniflux && cd ~/stacks/miniflux

    Create docker-compose.yml:

    services:
      miniflux:
        image: miniflux/miniflux:latest
        container_name: miniflux
        environment:
          DATABASE_URL: postgres://miniflux:secret@miniflux-db/miniflux?sslmode=disable
          BASE_URL: http://localhost:8082
        ports:
          - "8082:8080"
        depends_on:
          - miniflux-db
        restart: unless-stopped
    
      miniflux-db:
        image: postgres:16-alpine
        container_name: miniflux-db
        environment:
          POSTGRES_USER: miniflux
          POSTGRES_PASSWORD: secret
          POSTGRES_DB: miniflux
        volumes:
          - miniflux_db:/var/lib/postgresql/data
        restart: unless-stopped
    
    volumes:
      miniflux_db:

    Three things in that file matter, and two of them trip people up:

    1. ?sslmode=disable at the end of the DATABASE_URL — the current image attempts an SSL connection by default. Without this parameter the container enters a restart loop (see Step 3).
    2. secret as the password is fine for a LAN-only deployment, but if this server ever reaches the internet behind a proxy, change it to something real.
    3. BASE_URL is used for redirects and feed links. Set it to whatever address you will actually type in the browser.

    Step 2: Start it

    docker compose up -d
    docker compose ps

    Both containers should show Up. Wait ten seconds, then open http://YOUR_SERVER_IP:8082 (or http://localhost:8082 if you are on the same machine).

    Step 3: The restart loop (and the fix)

    If instead you see Restarting in docker compose ps, check the logs:

    docker logs miniflux

    If the output repeats pq: SSL is not enabled on the server, the container is talking to Postgres with SSL on and Postgres has it off. The fix is the ?sslmode=disable parameter on the DATABASE_URL line, which the compose file above already includes. If you are reading this guide because of that error, that one parameter is the fix.

    Edge case: schema version mismatch

    A second, rarer message is the database schema is not up to date: current=v0 expected=vNNN. This happens when a fresh database is created but the first container run aborts before migrations. Running the image once with migrations forced clears it:

    docker run --rm --network miniflux_default \
      -e DATABASE_URL="postgres://miniflux:secret@miniflux-db/miniflux?sslmode=disable" \
      -e RUN_MIGRATIONS=true miniflux/miniflux:latest

    That command runs the migrations and then starts the server (leave it running until the DB is migrated, or stop it after a few seconds) — after which the compose-managed container starts cleanly. (We hit this during testing; it is not part of the normal path, but it is the other error that appears in every Miniflux+Postgres thread.)

    Step 4: First-run setup

    The first visit shows the setup page. Create your admin account — Miniflux generates an initial password it shows you once (or sets one you choose, depending on version).

    Then:

    1. Add your first feed: paste an RSS URL into the “Add feed” field. If a site has no visible RSS link, try appending /feed, /rss, or /atom.xml to its URL, or use a feed-directory site to find it.
    2. Add the 10–15 feeds you actually read. Resist adding 200 — a full feed list you never finish is the same as not reading.
    3. Check “Polling interval” in settings: the default is hourly, which is plenty. Faster polling on a small machine just costs CPU for no reading benefit.

    Step 5: Use it from your phone

    Miniflux speaks the standard /api/v1 RSS reader API. Any of these clients work:

    • Reeder (iOS/macOS) — connect to your server URL, use the API
    • NetNewsWire (macOS/iOS) — same
    • Fluss (Android) — the most polished free option on Android
    • The built-in mobile view — Miniflux serves a decent mobile UI at /m, which is honestly good enough for daily use

    Resource usage (measured)

    Container Idle RAM Notes
    miniflux 17.2 MiB Go binary, one process
    postgres:16-alpine 37.6 MiB Alpine image keeps it small

    Both together: under 55 MiB at idle. A 1 GB Raspberry Pi can run this and still have room for a few more services.

    Updating

    Miniflux migrates its own schema on startup, so updating is:

    docker compose pull
    docker compose up -d

    Your data lives in the miniflux_db volume and survives every update. Back it up with docker run --rm -v miniflux_db:/data miniflux/miniflux:latest psql ... or, more simply, docker exec miniflux-db pg_dumpall > backup.sql on a cron schedule. (We have a dedicated backups guide in the pipeline.)

    FAQ

    Does Miniflux work without Postgres?

    It also supports SQLite and MySQL, but Postgres is the recommended production database and the one used here. SQLite is fine for a single-user test, but the image’s default expectations are Postgres-centric.

    Can I add multiple users?

    Yes — from the admin panel. Each user gets their own feeds and reading state, which makes Miniflux work as a small family reader.

    Should I expose port 8082 to the internet?

    No. Keep it on the LAN and reach it remotely via Tailscale or a reverse proxy with authentication — see the Security & Networking guides. RSS readers are a magnet for credential-stuffing bots the moment they are publicly reachable.

    Where does this fit in a bigger setup?

    In our self-hosting starter guide, Miniflux is one of the three first services, alongside Navidrome and DokuWiki.

  • The Self-Hosting Starter Guide: From Zero to a Working Home Server

    The Self-Hosting Starter Guide: From Zero to a Working Home Server

    Beginner · 10 min · Linux · Docker

    Tested on:

    OS Ubuntu 24.04 LTS (Debian 12 works too)
    Docker 29
    Hardware 4-core x86, 16 GB RAM
    Software Starter stack (Miniflux, PostgreSQL 16, Navidrome, DokuWiki)

    Last tested: 22 August 2026

    You do not need a rack of servers to start self-hosting. You need one machine, Docker, and a few well-chosen applications. This guide takes you from a blank Linux machine to a working home server with a working RSS reader, a personal music server, and a private wiki — every file tested on real hardware.

    Why self-host at all?

    Every month you pay for another subscription, you are renting someone else’s computer. Self-hosting flips the model: you buy the hardware once (or reuse what you already have) and run the software yourself. The benefits, in order of how they matter to real users:

    • Your data stays yours. Photos, music, notes, and feeds live on your disk, on your terms, with your backup strategy.
    • No subscription fatigue. A home server running four services costs a few pounds per month in electricity, not four monthly fees that keep going up.
    • Privacy by architecture. Your reading habits, your playlists, and your notes never pass through a company that may change its policies tomorrow.
    • You actually learn infrastructure. Networking, containers, reverse proxies, backups — the skills transfer directly to paid work.

    The honest trade-offs: you are the IT department now. Updates, outages, and security patches are your responsibility. A home server also needs a real IP address or a workaround (Tailscale, Cloudflare Tunnel) to be reached from outside your house — we cover that in the security series.

    Step 1: Choose your hardware

    You have three sensible starting points, depending on budget:

    Option A: Repurpose an old PC (free)

    Any x86 machine from roughly the last decade works as a starter server. The practical minimum: 8 GB of RAM, a solid-state drive (even a cheap SATA SSD makes a huge difference), and a power supply you trust. Old desktops are the classic choice, and a single 60 W machine idling costs roughly £15–25 per year at UK rates.

    Option B: Raspberry Pi 5 (around £80–100)

    The 16 GB model is the sweet spot for a starter stack: it runs the apps in this guide comfortably, idles around 5 W, and fits on a shelf. Use a quality case with active cooling and a 2.5″ SATA SSD via the HAT if you plan to store media — the Pi’s microSD slot will die on you under sustained writes.

    Option C: Used mini PC (around £150–250)

    Used Intel NUCs, Dell OptiPlexes, and HP Elites from office clearances offer x86 performance at a fraction of the price of new hardware. This is the best bang-per-pound if you want headroom for media transcoding later.

    Step 2: Install an operating system

    For a dedicated server, use a minimal Linux install rather than a desktop:

    • Debian 12 (bookworm): the safest default. Minimal install, no desktop, extremely stable, huge community.
    • Ubuntu Server 24.04 LTS: the friendlier choice if you want the most tutorials to match. Also an excellent default.
    • Truenas Scale or Proxmox: skip these for your first server. They add virtualisation and ZFS, which are powerful but premature until you know what you are running.

    During installation: give the machine a fixed IP on your LAN (or reserve one in your router’s DHCP table), and set a hostname like server. You will not want to remember a changing IP.

    Step 3: Install Docker

    Docker packages software into containers: isolated environments that start in seconds, take up only what they use, and are identical on any Linux machine. This is what makes self-hosting actually manageable instead of a tangle of system packages.

    On Debian or Ubuntu, the official install is a few lines:

    sudo apt-get update
    sudo apt-get install -y ca-certificates curl
    sudo install -m 0755 -d /etc/apt/keyrings
    sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \ https://download.docker.com/linux/$(. /etc/os-release && echo $ID) \ $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt-get update
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

    Then add your user to the docker group so you stop typing sudo:

    sudo usermod -aG docker $USER
    # log out and back in, then verify:
    docker compose version

    If that command prints a version number, you are ready.

    Step 4: Pick your first stack

    This is the part most guides get wrong. They hand you a list of forty apps and you spend two weeks configuring Sonarr and Prowlarr before you have used anything. Start with three services that you will actually touch every day:

    App What it does Why first
    Miniflux RSS reader — aggregates every feed you follow Instant daily value; your reading no longer depends on an algorithm
    Navidrome Personal music server — streams your library to any device One folder, one app, works with the official Substreamer app
    DokuWiki Plain-text wiki for notes and documentation Zero-friction writing; your notes are files on disk, not a proprietary format

    Each of these has a dedicated guide on this site with the exact compose file, tested setup steps, and the real errors we hit along the way:

    Step 5: Run the stack

    Everything below was verified on a 4-core / 16 GB Ubuntu machine with Docker 29. Create a project directory:

    mkdir -p ~/stacks/starter/music && cd ~/stacks/starter

    Drop in a docker-compose.yml with the three services (full annotated files in each linked guide):

    services: miniflux: image: miniflux/miniflux:latest container_name: miniflux environment: DATABASE_URL: postgres://miniflux:secret@miniflux-db/miniflux?sslmode=disable BASE_URL: http://localhost:8082 ports: - "8082:8080" depends_on: - miniflux-db restart: unless-stopped miniflux-db: image: postgres:16-alpine container_name: miniflux-db environment: POSTGRES_USER: miniflux POSTGRES_PASSWORD: secret POSTGRES_DB: miniflux volumes: - miniflux_db:/var/lib/postgresql/data restart: unless-stopped navidrome: image: deluan/navidrome:latest container_name: navidrome ports: - "4533:4533" environment: ND_SCANSCHEDULE: 1h ND_LOGLEVEL: info volumes: - ./music:/music:ro - navidrome_data:/data restart: unless-stopped dokuwiki: image: dokuwiki/dokuwiki:stable container_name: dokuwiki ports: - "8081:80" volumes: - dokuwiki_data:/dokuwiki/data - dokuwiki_conf:/dokuwiki/conf restart: unless-stopped volumes: miniflux_db: navidrome_data: dokuwiki_data: dokuwiki_conf:

    Then start it:

    docker compose up -d
    docker compose ps

    All four containers should show Up. The ports: Miniflux on :8082, DokuWiki on :8081, Navidrome on :4533. Open them from your laptop on the same network: http://SERVER_IP:8082, and so on.

    Step 6: The three first-run tasks

    1. Miniflux: first visit asks you to create the admin account. Then add feeds — start with the 10 you actually read. If the container keeps restarting with pq: SSL is not enabled on the server, your DATABASE_URL is missing ?sslmode=disable (full fix in the Miniflux guide).
    2. Navidrome: put MP3/FLAC files in the music/ folder, then create your first account at :4533. It scans the library on first login. The official mobile app (Substreamer) pairs in one minute.
    3. DokuWiki: first visit runs a tiny config wizard (admin login, language). That is the whole setup.

    Measured resource usage

    Because we run this stack, here is what it actually costs, measured with docker stats after a day of normal use (RSS polling, a music session, some wiki edits):

    Container Idle RAM Idle CPU
    miniflux 17 MiB ~0%
    miniflux-db (Postgres) 38 MiB ~0%
    navidrome 26 MiB ~0%
    dokuwiki 25 MiB ~0%

    Total: about 106 MiB of RAM for a full starter stack. A Raspberry Pi 5 with 4 GB has 40× the headroom this needs. The real cost of this stack is the electricity of the machine it lives on — which you were already paying.

    What comes next

    Once these three are boring (the goal), the natural expansion path is:

    • Nextcloud or Immich for photos and files (see the NAS & Media section)
    • AdGuard Home for network-wide ad and tracker blocking (Security & Networking)
    • A reverse proxy (Caddy or Nginx Proxy Manager) plus Tailscale, so the stack is reachable from anywhere without opening ports on your router — this is the single highest-value upgrade after the starter stack, and we cover it in the security series
    • Monitoring: Uptime Kuma, so your server tells you it is down instead of you finding out

    Frequently asked questions

    Is self-hosting safe if I am not a security expert?

    Yes, with discipline: keep Docker updated, use a reverse proxy with TLS instead of exposing ports, and do not expose admin interfaces directly to the internet. The starter stack above is LAN-only, which is the safe default. Our Security & Networking guides cover hardening step by step.

    Docker or Kubernetes?

    Docker Compose. Kubernetes on a home server is solving a problem you do not have. You will use 90% of what Compose gives you for 10% of the complexity.

    Can I run this on a VPS instead of at home?

    The same compose file runs unchanged on a VPS — that is part of Docker’s point. A VPS is a fine starting point if your home connection is bad or your ISP blocks inbound connections.

    What about the initial hardware cost?

    If you already own a spare PC, the marginal cost is electricity (a few pounds a month). A Raspberry Pi 5 path is around £100–150 all-in. After that, most services are free software. That is the whole pitch: one small fixed cost instead of an open-ended subscription stack.