RSS-ридеры на VPS: Miniflux, FreshRSS и ещё 3
Сравните Miniflux, FreshRSS, CommaFeed, yarr и Tiny Tiny RSS: память, базы данных, Fever и Google Reader API, а также поведение обновлений.
Какой self-hosted RSS-ридер выбрать для небольшого VPS
Miniflux — self-hosted RSS-ридер для небольшого VPS. Он состоит из одного бинарного файла на Go и PostgreSQL. Он поддерживает API Fever и Google Reader, поэтому к нему подключаются сторонние мобильные приложения. Обновление выполняется за один docker compose pull. Выберите FreshRSS, если вам нужны расширения и один контейнер со встроенным SQLite.
На VPS стоит разместить пять ридеров: Miniflux, FreshRSS, CommaFeed, yarr и Tiny Tiny RSS. В этой статье сравниваются их реальные различия: сколько памяти требуется каждому стеку, какую базу данных предполагает каждый вариант, какой API синхронизации нужен мобильному приложению и что происходит во время обновления. Все приведённые здесь значения либо опубликованы разработчиками проектов, либо получены простым расчётом; в тексте указано, какой именно это случай. Эти данные не являются результатами тестирования вашего оборудования, поэтому измерьте собственный сервер с помощью docker stats.
Пять читалок, по одному абзацу на каждую
Miniflux написан на Go и поставляется в виде единого статически скомпилированного бинарного файла. В документации прямо указана единственная жесткая зависимость: он «работает только с PostgreSQL». Режима SQLite нет. Программа предлагает REST API, а также API, совместимые с Fever и Google Reader, плюс импорт и экспорт OPML. Полнотекстовый поиск возложен на PostgreSQL, что отчасти объясняет, почему база данных является обязательной.
FreshRSS написан на PHP и работает как один контейнер, содержащий и веб-сервер, и само приложение. SQLite используется по умолчанию и не требует отдельного сервиса, в то время как PostgreSQL и MySQL поддерживаются для более крупных инсталляций. Программа поддерживает API Google Reader и Fever. Установка уже описана в нашем руководстве по FreshRSS на VPS, поэтому на этой странице проводится сравнение, а не повторение процесса установки.
CommaFeed написан на Java с использованием Quarkus, а его интерфейс копирует Google Reader. База данных выбирается на этапе сборки, а не во время выполнения, поэтому проект публикует по одному образу для каждой СУБД: athou/commafeed:latest-h2 для встроенной базы H2, athou/commafeed:latest-postgresql для PostgreSQL, а также варианты для MySQL и MariaDB. Эти теги представляют собой нативно скомпилированные сборки, а суффикс -jvm обозначает варианты, работающие на JVM. Программа предоставляет REST API, API, совместимый с Fever, а начиная с версии 7.3.0 (август 2026 года) — и API, совместимый с Google Reader.
yarr (yet another rss reader) представляет собой один бинарный файл на Go со встроенным SQLite, который вообще не требует контейнеров. Обычный запуск ./yarr открывает прослушивание на 127.0.0.1:7070. Флаги короткие: -addr 0.0.0.0:7070 -auth alice:secret открывает доступ к сети с защитой паролем, а -db /data/yarr.db позволяет разместить базу данных в нужном месте. Поддерживается API, совместимый с Fever. Последний тегированный релиз — v2.9 от сентября 2026 года, проверенный в октябре 2026 года; он последовал за v2.7 в июне и v2.8 в июле, что говорит о возобновлении активной разработки.
Tiny Tiny RSS — старейший из пяти проектов и самый тяжелый в запуске. Оригинальный проект на tt-rss.org был закрыт 1 ноября 2025 года, разработка продолжается в форке сообщества по адресу github.com/tt-rss/tt-rss, документация которого теперь является официальным руководством по настройке. Эта настройка включает четыре сервиса: контейнер с PostgreSQL, контейнер с приложением PHP-FPM, отдельный контейнер-обновлятор для получения лент и фронтенд-контейнер с nginx. В документации прямо указано, что «эта установка использует PostgreSQL». У проекта есть собственный JSON API, который используют его Android-клиент и несколько сторонних приложений. Поддержка Fever отсутствует.
Сколько памяти требуется каждому стеку
Приведённые ниже значения — это бюджеты, а не результаты измерений: максимальный объём памяти, в пределах которого каждый стек должен работать на небольшом VPS. Значение для CommaFeed взято из опубликованного примера проекта: для контейнера установлен предел 256 MB. Для остальных стеков указаны пределы с запасом для загрузчика лент. Именно он потребляет больше памяти при запуске цикла обновления.
Данные, на которых построен график
[
{
"label": "yarr (SQLite)",
"containers": 1,
"mem_limit_mb": 128
},
{
"label": "FreshRSS (SQLite)",
"containers": 1,
"mem_limit_mb": 256
},
{
"label": "CommaFeed (H2)",
"containers": 1,
"mem_limit_mb": 256
},
{
"label": "Miniflux + Postgres",
"containers": 2,
"mem_limit_mb": 320
},
{
"label": "Tiny Tiny RSS",
"containers": 4,
"mem_limit_mb": 640
}
]yarr требует меньше всего памяти — 128 MB, поскольку состоит из одного бинарного файла и одного файла SQLite. Ему не нужны отдельный сервер базы данных и среда выполнения языка. Miniflux требует 320 MB для 2 контейнеров. Большая часть этого объёма приходится на PostgreSQL, а не на Miniflux. Tiny Tiny RSS является исключением: ему требуется 640 MB для 4 контейнеров. Приложение, обновляющий процесс, база данных и веб-сервер работают как четыре отдельных процесса, каждый со своей кучей.
Задайте эти значения как реальные ограничения, а не как желаемые показатели. В разделе Ограничения памяти в Docker Compose описаны синтаксис и поведение контейнера при достижении предела. Контейнер без ограничения не завершает работу корректно при полном заполнении памяти сервера: kernel выбирает процесс и завершает его. Часто это оказывается не тот контейнер, который создал дефицит памяти.
Какую базу данных навязывает каждый ридер
База данных — это главное эксплуатационное различие между этими пятью решениями. Это более важное решение, чем любые отличия в пользовательском интерфейсе, так как от него зависят процедура резервного копирования и риски при обновлении.
PostgreSQL требуется для Miniflux и официальной установки Tiny Tiny RSS. Она обеспечивает полноценный полнотекстовый поиск и безопасную параллельную запись. Платой за это становится второй контейнер, отдельный том и одна повторяющаяся проблема: официальные образы PostgreSQL не умеют выполнять миграцию данных между мажорными версиями «на месте». Документация Tiny Tiny RSS прямо говорит об этом и предупреждает, что «официальные контейнеры PostgreSQL не поддерживают миграцию данных между мажорными версиями». Для RSS-ридера у вас есть два реалистичных варианта: зафиксировать старую мажорную версию или использовать дамп и восстановление с помощью pg_dump и pg_restore. PostgreSQL также описывает pg_upgrade и обновления на основе репликации, которые оправдывают дополнительные затраты на настройку для больших баз данных, где критичен простой, но база данных RSS-ридера редко относится к таким. Планируйте это мероприятие раз в год или два.
SQLite — это стандартный выбор для FreshRSS и yarr. Один файл, никакого сервера, портов или паролей. Она отлично справляется с нагрузкой одного пользователя с несколькими сотнями лент, но замедляется, когда несколько пользователей пишут данные одновременно — именно в этот момент опция PostgreSQL во FreshRSS начинает оправдывать себя. В версии v2.7 в yarr добавили опциональную поддержку PostgreSQL, но встроенный файл остается стандартным способом запуска.
H2 — это встроенная база данных по умолчанию для CommaFeed, и она заслуживает внимания перед началом работы, так как CommaFeed выбирает базу данных в момент сборки образа. Переход с H2 на PostgreSQL позже — это не просто изменение конфигурации. Это использование другого образа и миграция данных, которую вам придется выполнять самостоятельно, поэтому примите решение до того, как в системе накопится история чтения за год.
Будет ли работать мобильное приложение
Этот вопрос важнее, чем кажется на первый взгляд, поскольку веб-интерфейс — это лишь половина того, как обычно используются агрегаторы лент.
Miniflux поддерживает API, совместимые с Fever и Google Reader, поэтому большинство клиентов для iOS и Android успешно подключаются к нему. FreshRSS поддерживает те же два API, и в его документации приводится их сравнение: API Google Reader считается «лучшим» с полной поддержкой функций, тогда как API Fever обладает «ограниченным функционалом и менее эффективен». Для FreshRSS также требуется выполнить два действия перед тем, как приложение сможет авторизоваться. Включите «Allow API access (required for mobile apps)» в разделе Authentication, а затем создайте API-пароль в профиле пользователя. Если пропустить создание API-пароля, приложение выдаст ошибку авторизации, хотя вход через веб-интерфейс продолжит работать; это часто сбивает с толку, пока вы не поймете, где искать причину.
CommaFeed теперь также поддерживает оба API: он давно работает с Fever, а в версии 7.3.0 была добавлена поддержка API Google Reader для приложений, которые не работают с Fever. Используйте версию 7.3.0 или новее, если ваше приложение поддерживает только Google Reader. yarr предоставляет только API, совместимый с Fever, поэтому он работает с клиентами, поддерживающими Fever, но не с приложениями, работающими исключительно через Google Reader. Tiny Tiny RSS использует собственный API, что означает необходимость использования клиента, написанного специально для него. Убедитесь, что выбранное вами приложение поддерживает агрегатор, прежде чем импортировать в него 300 лент.
Рабочий compose-файл для сервера с 1 ГБ ОЗУ
Это стек Miniflux, адаптированный из официального примера Docker по состоянию на октябрь 2026 года. Опубликованный порт привязан к loopback, адрес прослушивания задан явно, а для обоих контейнеров установлены лимиты потребления памяти.
services:
miniflux:
image: miniflux/miniflux:latest
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
depends_on:
db:
condition: service_healthy
environment:
- DATABASE_URL=postgres://miniflux:CHANGE_ME@db/miniflux?sslmode=disable
- LISTEN_ADDR=0.0.0.0:8080
- BASE_URL=https://rss.example.com/
- RUN_MIGRATIONS=1
- CREATE_ADMIN=1
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=CHANGE_ME_TOO
- POLLING_FREQUENCY=60
healthcheck:
test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"]
mem_limit: 128m
db:
image: postgres:18
restart: unless-stopped
environment:
- POSTGRES_USER=miniflux
- POSTGRES_PASSWORD=CHANGE_ME
- POSTGRES_DB=miniflux
volumes:
- miniflux-db:/var/lib/postgresql
healthcheck:
test: ["CMD", "pg_isready", "-U", "miniflux"]
interval: 10s
start_period: 30s
mem_limit: 192m
volumes:
miniflux-db:В этом файле есть три строки, в которых часто допускают ошибки. LISTEN_ADDR=0.0.0.0:8080 дублирует настройки, уже заданные в официальном образе в его Dockerfile, поэтому вместе с miniflux/miniflux это скорее полезная мера предосторожности, чем исправление. Это важно, если вы собираете собственный образ или запускаете упакованный бинарный файл, так как значение по умолчанию для него — 127.0.0.1:8080. Процесс, привязанный к loopback внутри контейнера, недоступен через опубликованный порт, из-за чего вы получите сброс соединения при внешне исправном контейнере. Путь к тому /var/lib/postgresql соответствует PostgreSQL 18; версия 17 и более ранние хранят данные в /var/lib/postgresql/data. Монтирование неверного пути означает, что каталог с данными не попадает на том, и всё содержимое исчезнет при следующем пересоздании контейнера. 127.0.0.1:8080:8080 защищает порт от доступа из публичного интернета, так как публикация порта без указания адреса добавляет правило в цепочку, которой не управляет ufw. В обход ufw через Docker ports объясняется этот механизм, а в обратный прокси Traefik описано, как настроить перед ним TLS.
docker compose up -d
docker compose ps
docker compose logs -f miniflux
docker stats --no-streamdocker compose ps должен показать оба сервиса как запущенные, при этом база данных будет помечена как healthy. При первом запуске Miniflux в логах отображаются миграции схемы, которые инициирует RUN_MIGRATIONS=1. docker stats --no-stream выводит текущее потребление памяти — это число нужно сравнить с лимитами, указанными выше. Если контейнер Miniflux перезапускается в цикле, изучите его лог: connect: connection refused означает, что он запустился раньше, чем PostgreSQL был готов принимать соединения. Именно это предотвращает условие service_healthy, поэтому убедитесь, что оно сохранилось после ваших правок. Если вы только начинаете работать с Compose, основы Docker Compose на VPS помогут разобраться со структурой файлов.
Что не поместится на сервер с 1 GB ОЗУ
Tiny Tiny RSS — это сервис, от которого стоит отказаться. Его официальный стек из четырех компонентов работает на VPS с 1 GB ОЗУ только в том случае, если на сервере больше ничего не запущено, и он не соседствует с другими приложениями, использующими базу данных, или reverse proxy. Четыре сервиса означают четыре набора накладных расходов, один из которых — PostgreSQL.
CommaFeed поместится, но только с образом H2 и ограничением в 256 MB, которое задано в официальном примере проекта. Комбинация, которая перегружает небольшой сервер — это CommaFeed вместе с отдельным сервером баз данных. Варианты образов -jvm усугубляют ситуацию: документация проекта предупреждает, что JVM по умолчанию потребляет много памяти и не возвращает неиспользуемые ресурсы операционной системе. Теги latest-h2 и latest-postgresql — это нативные сборки, которые проект рекомендует из-за меньшего потребления памяти, поэтому используйте их, если у вас нет веских причин запускать JVM.
Когда на сервере заканчивается память, механизм kernel out of memory killer выбирает процесс и завершает его. dmesg -T показывает строку вида Out of memory: Killed process 1234 (java), и контейнер просто исчезает из docker compose ps без каких-либо сообщений в логах приложения, так как приложение не успевает их записать.
Особенности обновления каждого сервиса
- Miniflux:
docker compose pull && docker compose up -d, миграции схемы базы данных применяются при запуске, если установлена переменнаяRUN_MIGRATIONS=1. Риск при обновлении связан не с Miniflux, а с мажорной версией PostgreSQL, на которой он работает. - FreshRSS: загрузите новый образ. При использовании SQLite обновлять движок базы данных не нужно, поэтому типичные проблемы возникают из-за сторонних расширений, которые не были обновлены.
- CommaFeed: загрузите вариант образа, соответствующий вашей базе данных. Переход с
latest-h2наlatest-postgresqlне переносит ваши данные. - yarr: замените исполняемый файл, сохранив файл базы данных. Релизы выходили в июне, июле и сентябре 2026 года, версия v2.9 является актуальной на октябрь 2026 года, поэтому периодически проверяйте страницу релизов.
- Tiny Tiny RSS:
docker compose pull && docker compose up -d. Контейнер приложения обновляется самостоятельно при запуске. Согласно FAQ проекта, ошибки обновления схемы связаны с повреждением тома или некорректными переопределениями (override), поэтому в случае их появления проверьте эти параметры в первую очередь. Если ваш compose-файл всё ещё загружает образы из закрытого проекта tt-rss.org, переключитесь на образы форка (supahgreg/tt-rssна Docker Hub илиghcr.io/tt-rss/tt-rss).
Создавайте дамп базы данных до начала любых операций, а не после.
docker compose exec -T db pg_dump -U miniflux miniflux | gzip > miniflux-$(date +%F).sql.gzСколько трафика требует интервал обновления
Приведённые ниже значения получены расчётным путём, а не измерены. Они рассчитаны для 100 лент, одного запроса к каждой ленте за интервал и 40 KB на ответ. Фактический трафик обычно ниже, если сервер обрабатывает условные запросы, и выше, если ленты содержат полный текст статей.
Данные, на которых построен график
[
{
"label": "Every 5 minutes",
"fetches_per_month": "864,000",
"gb_per_month": 34.6
},
{
"label": "Every 15 minutes",
"fetches_per_month": "288,000",
"gb_per_month": 11.5
},
{
"label": "Every 30 minutes",
"fetches_per_month": "144,000",
"gb_per_month": 5.8
},
{
"label": "Every 60 minutes",
"fetches_per_month": "72,000",
"gb_per_month": 2.9
}
]Интервал в пять минут для 100 лент составляет 864,000 запросов и примерно 34.6 GB в месяц. При опросе раз в час получается 72,000 запросов и около 2.9 GB. В Miniflux параметр POLLING_FREQUENCY по умолчанию установлен в 60 минут. Это последняя строка на этой диаграмме, и такое значение подходит почти всем. Статья не появится раньше только потому, что вы чаще запрашиваете ленту.
Именно условные запросы удерживают фактический показатель ниже расчётного. Клиент, который сохраняет заголовки ETag и Last-Modified, полученные от ленты, отправляет их обратно как If-None-Match и If-Modified-Since, а сервер без новых данных отвечает кодом 304 Not Modified без тела ответа. Соединение всё равно требует handshake, но полезная нагрузка не передаётся. Ленты, которые игнорируют условные запросы, каждый раз передают весь документ. Поэтому несколько крупных лент могут самостоятельно формировать основную часть расходов на трафик.
Слишком частый опрос также может привести к блокировке. Сервер, который решит, что вы отправляете слишком много запросов, ответит кодом 429 Too Many Requests, а некоторые сайты используют вместо этого код 403. Miniflux сохраняет последнюю ошибку для самой ленты. Поэтому список лент — первое место, которое следует проверить, если одна лента перестала обновляться, а остальные продолжают работать.
Ленты умирают, а OPML-файл — это не резервная копия
Ленты устаревают быстрее, чем вы ожидаете. Домены перестают продлеваться, сайты переезжают на платформы без поддержки лент, а URL, который раньше отдавал XML, начинает возвращать HTML-страницу с ошибкой и статусом 200 OK. Последний случай — самый неудобный: запрос проходит успешно, но парсинг завершается неудачей, и ваш агрегатор фиксирует ошибку парсинга, а не сетевую ошибку. Раз в год сортируйте список лент по дате последнего обновления и удаляйте те, которые перестали обновляться.
Экспорт в формате OPML — это ваш список подписок. Стандартный OPML-файл содержит только URL лент и названия папок. FreshRSS добавляет собственное пространство имен XML, в котором хранятся индивидуальные настройки лент, такие как интервал обновления, XPath-селекторы для парсинга и фильтры автоматической пометки прочитанным. Однако ни один экспорт OPML не сохраняет статус прочтения, избранные статьи или текст сохраненных вами материалов. Если импортировать такой OPML в чистую установку, вы получите свои ленты обратно, но все когда-либо прочитанные статьи снова будут помечены как непрочитанные.
Резервная копия, которая действительно важна, — это база данных. Для PostgreSQL команда pg_dump, приведенная выше, полностью решает задачу. Для агрегаторов на базе SQLite, таких как FreshRSS или yarr, остановите процесс записи и скопируйте файл или создайте консистентную копию во время работы с помощью sqlite3 yarr.db ".backup '/tmp/yarr-backup.db'". Обычная команда cp для базы данных, в которую в этот момент идет запись, может привести к созданию файла, который впоследствии не откроется, так как копия зафиксирует незавершенную операцию записи. Регулярно переносите эти файлы с сервера по расписанию — именно для этого нужны резервные копии restic на VPS, и хотя бы раз восстановите данные в тестовом контейнере, чтобы убедиться, что процедура работает.
Агрегатор лент — один из самых дешевых сервисов для самостоятельного хостинга, поэтому он присутствует в каждом списке проектов, которые стоит разместить на своем сервере в 2026 году. Разместите рядом собственный экземпляр SearXNG, и как чтение, так и поиск будут выполняться на оборудовании, которое вы контролируете.
FAQ
Какой self-hosted RSS-ридер потребляет меньше всего оперативной памяти?
yarr. Это один бинарный файл на Go со встроенной SQLite, поэтому для него не требуется отдельный сервер баз данных или дополнительные среды выполнения. Лимита в 128 МБ для него вполне достаточно. Платой за это является ограниченный функционал: поддерживается только Fever API, а последняя версия v2.9 вышла в сентябре 2026 года. Если вам нужна поддержка Google Reader API и полнотекстовый поиск при схожем потреблении ресурсов, лучшим выбором будет Miniflux вместе с PostgreSQL с лимитом 320 МБ.
Можно ли запустить self-hosted RSS-ридер на VPS с 1 ГБ ОЗУ?
Да. Miniflux с PostgreSQL укладывается примерно в 320 МБ, если установить mem_limit для обоих контейнеров, а FreshRSS с SQLite помещается в один контейнер. На 1 ГБ ОЗУ не рекомендуется запускать официальный стек Tiny Tiny RSS, так как он состоит из 4 сервисов, включая собственный экземпляр PostgreSQL. Всегда устанавливайте лимиты памяти, так как при нехватке ресурсов на сервере ядро принудительно завершит процесс (OOM killer), и часто под удар попадает база данных, а не само приложение, вызвавшее перерасход.
Какие из этих решений работают с RSS-клиентами для iOS и Android?
Miniflux, FreshRSS и CommaFeed версии 7.3.0 и выше поддерживают API, совместимые с Fever и Google Reader, поэтому к ним можно подключить почти любой мобильный клиент. yarr поддерживает только Fever API. Tiny Tiny RSS использует собственный API, поэтому для него требуется специальный клиент. Во FreshRSS необходимо дополнительно включить доступ к API в разделе Authentication и задать отдельный пароль для API в профиле пользователя, иначе приложение не сможет авторизоваться, хотя доступ через веб-интерфейс будет работать.
Является ли экспорт в OPML резервной копией моего RSS-ридера?
Нет. OPML позволяет восстановить только список подписок. Расширенный экспорт во FreshRSS также сохраняет настройки отдельных лент и фильтры, но статус прочтения, избранные записи и текст статей хранятся только в базе данных. Создавайте резервную копию самой базы данных с помощью pg_dump для PostgreSQL или команды .backup для SQLite и копируйте полученный файл за пределы сервера.
Поддерживает ли Miniflux SQLite?
Нет. В документации проекта указано, что он «работает только с PostgreSQL», а полнотекстовый поиск реализован с использованием функций PostgreSQL, поэтому облегченного режима работы не предусмотрено. Если вам нужен ридер без отдельного контейнера с базой данных, используйте FreshRSS с бэкендом SQLite по умолчанию или yarr с его встроенным файлом базы данных.