Stack
- Docker + Docker Compose
- Traefik (reverse proxy, HTTPS, ACME)
- Miniflux
- PostgreSQL
No Kubernetes. No Helm. No unnecessary abstractions.
Architecture
Internet
|
Traefik (80 / 443, ACME)
|
Miniflux (:8080)
|
PostgreSQL
docker-compose.yml
Sensitive values (domains, credentials, email) are intentionally replaced.
services:
traefik:
image: traefik:v3.0
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.myresolver.acme.email=you@example.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
networks:
- proxy
miniflux:
image: miniflux/miniflux:2.2
depends_on:
- miniflux-db
environment:
DATABASE_URL: postgres://miniflux:password@miniflux-db/miniflux?sslmode=disable
RUN_MIGRATIONS: 1
CREATE_ADMIN: 1
ADMIN_USERNAME: admin
ADMIN_PASSWORD: admin_password
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.miniflux.rule=Host(`rss.example.com`)"
- "traefik.http.routers.miniflux.entrypoints=websecure"
- "traefik.http.routers.miniflux.tls.certresolver=myresolver"
- "traefik.http.services.miniflux.loadbalancer.server.port=8080"
miniflux-db:
image: postgres:15
environment:
POSTGRES_USER: miniflux
POSTGRES_PASSWORD: password
POSTGRES_DB: miniflux
volumes:
- ./miniflux/db:/var/lib/postgresql/data
networks:
- proxy
networks:
proxy:
external: false
First run (bootstrap)
docker compose up -d
On the first startup, Miniflux will:
- Run database migrations
- Create the admin user once
Log in and confirm everything works.
Remove bootstrap credentials
After the first successful login, remove the following variables:
CREATE_ADMIN
ADMIN_USERNAME
ADMIN_PASSWORD
Then restart:
docker compose up -d
Miniflux does not recreate users once the database exists. These variables are strictly one-time bootstrap helpers.
Operational notes
-
Do not use
latesttags in production -
Do not expose Miniflux ports when using Traefik
-
Secure ACME storage:
chmod 600 letsencrypt/acme.json -
Back up
./miniflux/dbregularly
Why Miniflux
- No tracking
- No recommendation engine
- No UI clutter
- Fast and predictable
You subscribe to feeds. You read them. That’s it.
Read other posts