MAATRIX / Блог / Miniflux в Docker Compose: готовый файл

Miniflux в Docker Compose: готовый файл

MAATRIX

Большинство RSS-ридеров со временем обрастают тегами, папками, темами оформления, встроенным ридером статей с картинками — и это удобно, пока вам не захочется просто быстро долистать двести непрочитанных заголовков утром за кофе. Miniflux — противоположный полюс: один Go-бинарник, одна база PostgreSQL, интерфейс без единой лишней кнопки. Разворачивается на VPS через Docker Compose за пару минут, а после установки практически не требует внимания. Ниже — рабочий docker-compose.yml, разбор переменных окружения и то, что обычно упускают в первый день.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Чем Miniflux отличается от FreshRSS и других ридеров

Формально задача та же: опрашивать ленты, хранить записи, показывать непрочитанное. Разница — в философии.

MinifluxFreshRSS
Язык / рантаймGo, один статический бинарникPHP, нужен php-fpm
База данныхтолько PostgreSQLMySQL/MariaDB/PostgreSQL/SQLite на выбор
Планировщик обновления лентвстроен в сам процесс (worker pool)внешний cron
Интерфейсминималистичный, без тем и виджетовбольше настроек вида, темы оформления
Полнотекстовый поискесть (по PostgreSQL tsvector)есть
Категории/папкиплоский список категорийвложенные категории
OIDC/OAuth2-входвстроенчерез расширение

Ключевое практическое отличие — планировщик. FreshRSS сам ленты не опрашивает, для этого нужен внешний cron, как описано в статье про установку FreshRSS на Ubuntu 24.04. У Miniflux воркер обновления лент — часть самого процесса, отдельный планировщик не нужен вообще: контейнер поднялся — ленты обновляются по расписанию из настроек.

Если вам важны темы оформления, вложенные папки и гибкость под конкретный вкус — FreshRSS ближе. Если нужен инструмент, который не просит внимания месяцами и не ест память на десктопных функциях, — это Miniflux.

Готовый docker-compose.yml

Miniflux официально поддерживает только PostgreSQL — это осознанное упрощение авторов, не пытайтесь подключить MySQL или SQLite, штатной поддержки нет. Структура каталогов на сервере:

/opt/miniflux/
└── docker-compose.yml

Данные PostgreSQL хранятся в именованном volume, отдельная директория на хосте не нужна:

mkdir -p /opt/miniflux
cd /opt/miniflux
nano 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:замените-на-длинный-пароль@db/miniflux?sslmode=disable
      - RUN_MIGRATIONS=1
      - CREATE_ADMIN=1
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=замените-на-длинный-пароль-2
      - BASE_URL=https://rss.example.com

  db:
    image: postgres:16-alpine
    container_name: miniflux-db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=miniflux
      - POSTGRES_PASSWORD=замените-на-длинный-пароль
      - POSTGRES_DB=miniflux
    volumes:
      - miniflux-db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "miniflux"]
      interval: 10s
      start_period: 30s

volumes:
  miniflux-db:

Пароли в DATABASE_URL и POSTGRES_PASSWORD должны совпадать — это два места, где легко забыть поправить второе после смены первого. RUN_MIGRATIONS=1 заставляет контейнер накатить схему БД при первом старте (и при последующих обновлениях версии — миграции идемпотентны, повторный запуск с той же схемой ничего не ломает). CREATE_ADMIN=1 создаёт администратора из ADMIN_USERNAME/ADMIN_PASSWORD один раз при пустой базе; на повторных запусках, если пользователь уже есть, эти переменные просто игнорируются.

Запуск:

docker compose up -d
docker compose logs -f miniflux

В логах при первом старте должно быть видно применение миграций и создание администратора. Открывайте http://<IP-сервера>:8080 — интерфейс готов сразу, отдельного мастера установки, в отличие от FreshRSS, нет.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Переменные окружения: что стоит поправить сразу

Полный список переменных — в официальной документации проекта, но на практике в первый день имеет смысл тронуть несколько:

    environment:
      # ... предыдущие переменные ...
      - POLLING_FREQUENCY=60        # минут между опросами лент по умолчанию
      - BATCH_SIZE=100              # сколько лент опрашивать за один проход воркера
      - WORKER_POOL_SIZE=5          # параллельных воркеров опроса
      - CLEANUP_ARCHIVE_READ_DAYS=180  # автоудаление прочитанных старше N дней
      - LOG_LEVEL=info

POLLING_FREQUENCY=60 — разумный дефолт для личного использования; если следите за десятком новостных лент с высокой частотой публикаций, можно снизить до 15-20 минут, но учитывайте, что это создаёт больше нагрузки на серверы источников и на саму БД. WORKER_POOL_SIZE стоит поднимать только если лент действительно много (несколько сотен) и видно, что опрос не укладывается в интервал — для обычных 50-100 лент дефолтного значения хватает с запасом.

CLEANUP_ARCHIVE_READ_DAYS полезен, если не хотите, чтобы база бесконечно росла: старые прочитанные записи будут удаляться автоматически по расписанию. Если важен долгий архив прочитанного для поиска — переменную лучше не задавать (тогда очистка по возрасту отключена) и следить за размером БД вручную.

HTTPS через Caddy или Traefik

Miniflux — веб-интерфейс с логином и паролем, поднимать его на 80-м порту без TLS наружу не стоит. Проще всего добавить сервис за reverse proxy с автоматическим сертификатом. Пример для Caddy — добавьте в Caddyfile:

rss.example.com {
    reverse_proxy miniflux:8080
}

При такой схеме порт 8080:8080 в docker-compose.yml Miniflux наружу пробрасывать не обязательно — оставьте только внутреннюю docker-сеть между Caddy и Miniflux, а наружу смотрят только 80/443 самого Caddy. Как поднять сам Caddy с автовыпуском сертификатов — в статье про Caddy с авто-SSL на Ubuntu 24.04. Если на сервере уже стоит Traefik, а не Caddy, схема идентична — просто добавьте у Miniflux лейблы роутера вместо блока Caddyfile, отдельного мастер-класса для этого не нужно.

Не забудьте выставить BASE_URL в переменных окружения Miniflux на реальный внешний адрес с https:// — без этого некоторые ссылки внутри интерфейса и в OPML-экспорте будут генерироваться с неверным протоколом или хостом.

Мобильные клиенты, интеграции и API

Как и FreshRSS, Miniflux поддерживает Fever API и Google Reader-совместимый API — включаются в настройках профиля пользователя (Настройки → API-ключи / Fever API), после чего подключаются сторонние клиенты: Reeder, FeedMe, NetNewsWire, Fluent Reader, ReadKit и другие. У Miniflux есть и собственный REST API с токенами на пользователя — им пользуются официальные и сторонние CLI-утилиты и скрипты автоматизации.

Отдельно стоит остальных ридеров интеграция с внешними сервисами прямо из карточки статьи — без плагинов, встроено в ядро:

  • Отправка "в закладки": Wallabag, Pocket, Instapaper, Linkding, Shiori, Shaarli, Raindrop, Espial, Nunux Keeper, PinBoard;
  • Уведомления: Telegram-бот, Matrix, ntfy, Slack, Discord, Rocket.Chat, Webhook произвольного формата;
  • Полнотекстовое извлечение: встроенный scraper вытягивает полный текст статьи по правилам, если в RSS отдаётся только анонс — полезно для лент, которые режут контент нарочно ради переходов на сайт.

Настраиваются интеграции в Настройки → Интеграции, у каждого сервиса — своя пара полей (обычно API-токен и, если self-hosted вариант вроде Wallabag или Linkding, URL инстанса). Если у вас уже поднят self-hosted Wallabag или аналог для сохранения статей на потом — подключение занимает пару минут и избавляет от привычки держать двадцать вкладок открытыми "на почитать".

Для входа через единый SSO вместо локального пароля Miniflux умеет OIDC/OAuth2 — переменные OAUTH2_* в окружении контейнера подключают его к любому OIDC-провайдеру, в том числе self-hosted, например Authentik в Docker Compose. Для личного использования это избыточно, но если Miniflux — один из нескольких self-hosted сервисов за общим SSO, штатная поддержка OIDC избавляет от отдельного пароля именно для RSS-ридера.

Резервное копирование и обновление

Вся ценная информация — в PostgreSQL-volume miniflux-db, конфигурация приложения целиком описывается переменными окружения и нигде на диске отдельно не хранится. Бэкап сводится к дампу базы:

docker compose exec db pg_dump -U miniflux miniflux > miniflux-backup-$(date +%F).sql

Восстановление на новом сервере — поднять пустой стек тем же docker-compose.yml без CREATE_ADMIN (чтобы не создавать лишнего администратора поверх восстановленных данных) и залить дамп:

docker compose exec -T db psql -U miniflux miniflux < miniflux-backup-2026-08-20.sql

Если на сервере уже настроен общий пайплайн бэкапов, дамп можно направить туда же, что и остальные сервисы — например, через restic в Docker Compose, сделав дамп первым шагом в скрипте перед запуском restic.

Обновление — штатная процедура Compose, миграции БД накатываются автоматически благодаря RUN_MIGRATIONS=1:

docker compose pull
docker compose up -d

Перед обновлением на новую мажорную версию стоит один раз заглянуть в changelog проекта на GitHub — Miniflux развивается стабильно, ломающие изменения формата БД случаются редко, но резервный дамp перед апдейтом всё равно дешевле разбора проблем после.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли использовать MySQL или SQLite вместо PostgreSQL?

Нет, штатно Miniflux поддерживает только PostgreSQL — это решение авторов проекта ради простоты кода и предсказуемого поведения полнотекстового поиска, обходных путей через плагины нет.

Сколько ресурсов реально нужно?

Для личного использования с несколькими десятками лент достаточно 1 vCPU и 512 МБ — 1 ГБ RAM с запасом, основную часть памяти займёт PostgreSQL, а не сам Miniflux. Точные цифры зависят от числа лент и глубины хранимого архива, ориентируйтесь на эти значения как на стартовую точку, а не гарантию.

Как перенести подписки из другого ридера?

Через Настройки → Импорт/экспорт → Импортировать OPML — экспортируйте OPML-файл из FreshRSS, Feedly, Inoreader или другого источника, все категории и ленты перенесутся разом.

Нужен ли отдельный SSL-сертификат, если Miniflux уже за общим reverse proxy на сервере?

Нет, достаточно добавить блок для нового поддомена в существующий конфиг Caddy или Traefik — отдельный сертификат конкретно под Miniflux не нужен, если сертификат оформлен на весь домен или через wildcard.

Что делать, если после старта контейнер miniflux падает с ошибкой подключения к БД?

Почти всегда причина в depends_on без condition: service_healthy (тогда Miniflux стартует раньше, чем PostgreSQL готов принимать соединения) или в несовпадении пароля между DATABASE_URL и POSTGRES_PASSWORD — проверьте docker compose logs db на предмет "database system is ready to accept connections" и сверьте оба пароля построчно.

Есть ли тёмная тема и мобильная вёрстка интерфейса?

Да, интерфейс адаптивный и поддерживает тёмную тему через системные настройки браузера — но тем оформления на выбор, в отличие от FreshRSS, нет: минимализм здесь принципиальная позиция проекта, а не недоделанная функция.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →