Установка FreshRSS на VPS с Ubuntu 24.04
Пошаговое руководство по развертыванию FreshRSS на стеке Apache, PHP 8.3 и MariaDB. Узнайте, как настроить права доступа, cron для обновления лент и API для мобильных приложений.
Что вы создаете
Self-hosted RSS-ридер — это программа для чтения лент, которая работает на вашем собственном сервере. Никто не сможет отключить её или изменить контент, который вы видите. В этом руководстве FreshRSS устанавливается на VPS с Ubuntu 24.04: Apache в качестве фронтенда, PHP в качестве бэкенда, MariaDB для хранения данных и одна задача cron для получения новых статей. RSS (Really Simple Syndication) — это формат файла, который публикует сайт, чтобы стороннее ПО могло считывать его статьи. FreshRSS — это PHP-приложение, которое собирает эти файлы, хранит статьи и предоставляет веб-интерфейс, а также API (интерфейс прикладного программирования), с которым работают мобильные приложения.
Сама установка проста: распакуйте релиз, создайте базу данных, напишите конфигурацию виртуального хоста, запустите установщик из командной строки, а затем создайте учетную запись с помощью cli/create-user.php. Большая часть работы ниже — это этапы, на которых часто допускают ошибки: настройка обновления лент, кодирование слэшей для мобильного API и права доступа к файлам.
FreshRSS 1.30.4, выпущенный 21 октября 2026 года, является текущим релизом на 29 октября 2026 года. Ему требуется PHP 8.1 или новее. В Ubuntu 24.04 поставляется PHP 8.3, поэтому стандартных пакетов дистрибутива достаточно, и вам не нужно подключать сторонние репозитории PHP.
Начните с работающего стека LAMP
FreshRSS — это обычное PHP-приложение, поэтому для него требуется та же базовая среда, что и для любого другого. Если вы еще не подготовили эту базу, сначала выполните настройку стека LAMP для Ubuntu 24.04 и вернитесь сюда. Краткая версия:
sudo apt update
sudo apt install -y apache2 mariadb-server php libapache2-mod-php
sudo systemctl enable --now apache2 mariadbsystemctl status apache2 должен выводить active (running). Если Apache не запускается, обычная причина заключается в том, что другой процесс уже занял порт 80, и sudo ss -ltnp | grep :80 укажет его имя.
PHP-расширения, необходимые для FreshRSS
FreshRSS считает libxml, cURL, JSON, PDO_MySQL, PCRE и ctype обязательными. Также требуются mbstring, iconv, Zlib и ZipArchive, а на 32-битных системах — GMP. В Ubuntu они доступны в виде системных пакетов:
sudo apt install -y php-curl php-mbstring php-xml php-zip php-mysql php-intl php-gmp
sudo systemctl restart apache2Проверьте, какие расширения PHP загружены, с помощью php -m. Отсутствие расширения не препятствует запуску установщика. Проблема проявится на экране проверки требований в виде красной строки с названием расширения. Это не самый удобный способ обнаружить ошибку, поэтому лучше проверить всё заранее. Перезапуск Apache обязателен, так как libapache2-mod-php хранит PHP внутри процесса Apache, поэтому установленное расширение будет невидимо для веб-сервера до его перезагрузки.
Загрузка релиза
Установите FreshRSS вне стандартного корневого каталога веб-сервера и укажите на него в настройках Apache. Разделение каталога приложения и корневого каталога документов гарантирует, что через HTTP доступна только папка public.
cd /tmp
curl -fsSLO https://github.com/FreshRSS/FreshRSS/archive/refs/tags/1.30.4.tar.gz
tar xzf 1.30.4.tar.gz
sudo mv FreshRSS-1.30.4 /srv/freshrssТеперь настройте права доступа, к которым документация FreshRSS предъявляет строгие требования: пользователь веб-сервера должен владеть деревом каталогов, группа должна иметь права на чтение всех файлов, а также права на запись в ./data/.
sudo chown -R www-data:www-data /srv/freshrss
sudo chmod -R g+r /srv/freshrss
sudo chmod -R g+w /srv/freshrss/dataЕсли пропустить этот шаг, установщик завершится с ошибкой при записи конфигурации, так как PHP выполняется от имени www-data, а www-data не имеет прав на запись в каталог, принадлежащий root.
Создание базы данных
FreshRSS поддерживает SQLite, MariaDB, MySQL и PostgreSQL. Для SQLite требуется расширение php-sqlite3, но не требуется настройка сервера баз данных; данные каждого пользователя сохраняются в отдельном файле data/users/_user_/db.sqlite. При добавлении пользователей их записи не объединяются в один общий файл SQLite. В этом руководстве используется MariaDB как часть стека LAMP.
sudo mariadb -e "CREATE DATABASE freshrss CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mariadb -e "CREATE USER 'freshrss'@'localhost' IDENTIFIED BY 'ReplaceThisPassword';"
sudo mariadb -e "GRANT ALL PRIVILEGES ON freshrss.* TO 'freshrss'@'localhost';"
sudo mariadb -e "FLUSH PRIVILEGES;"Используйте utf8mb4, а не utf8. Ленты новостей содержат эмодзи и нелатинские символы, а старая трехбайтовая кодировка utf8 не поддерживает четырехбайтовые символы. Неподдерживаемые символы вызывают ошибку при работе MariaDB в стандартном строгом режиме; усечение данных зависит от SQL-режима и параметров операторов, таких как IGNORE.
Виртуальный хост Apache
Публичный каталог — это p/, а не корень дерева каталогов. Все остальные файлы, включая конфигурационный файл с паролем от базы данных, находятся выше document root, откуда Apache никогда не будет их отдавать.
<VirtualHost *:80>
ServerName rss.example.com
DocumentRoot /srv/freshrss/p/
<Directory /srv/freshrss/p>
AllowOverride AuthConfig FileInfo Indexes Limit
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/freshrss_error.log
CustomLog ${APACHE_LOG_DIR}/freshrss_access.log combined
AllowEncodedSlashes On
</VirtualHost>Сохраните это как /etc/apache2/sites-available/freshrss.conf и включите конфигурацию:
sudo a2enmod rewrite
sudo a2ensite freshrss
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2configtest должен вывести Syntax OK. Директива AllowEncodedSlashes On кажется необязательной, но это не так: API Google Reader отправляет идентификаторы лент, содержащие %2F, и без этой директивы Apache отклоняет их. В результате мобильные приложения перестают синхронизироваться, хотя веб-интерфейс продолжает работать корректно.
Добавьте HTTPS перед входом в систему
Вы собираетесь ввести пароль на этом сайте, поэтому сначала получите сертификат. Направьте A-запись на сервер, затем следуйте инструкции по настройке Certbot для Apache в Ubuntu и выполните sudo certbot --apache -d rss.example.com. Certbot перепишет конфигурацию виртуального хоста для порта 443 и добавит редирект. Проверьте результат с помощью curl -I https://rss.example.com/, команда должна вернуть 200 или перенаправление на страницу входа.
Запуск установщика из командной строки
FreshRSS поддерживает установку через браузер, однако версия для командной строки позволяет повторять процесс и сохраняет точную историю выбранных параметров.
sudo -u www-data php /srv/freshrss/cli/do-install.php \
--default-user admin --auth-type form --environment production \
--base-url https://rss.example.com --language en --api-enabled \
--db-type mysql --db-host localhost --db-user freshrss \
--db-password 'ReplaceThisPassword' --db-base freshrss
sudo -u www-data php /srv/freshrss/cli/create-user.php \
--user admin --password 'a-long-passphrase' --api-password 'a-different-passphrase'Выполняйте обе команды от имени www-data. Если запустить их от пользователя root, созданные файлы конфигурации будут принадлежать root, из-за чего веб-интерфейс впоследствии не сможет сохранять настройки. Параметр --environment production также важен, так как режим разработки выводит PHP-уведомления непосредственно на страницы сайта.
Загрузите https://rss.example.com/ и войдите в систему под учетной записью admin.
Почему ленты не обновляются автоматически
Никто не опрашивает ваши ленты, пока вы не дадите команду. Открытие FreshRSS не запускает планировщик получения лент; если планировщик не настроен, используйте ссылку обновления в меню навигации для ручной загрузки статей. Решение заключается в использовании скрипта, который поставляется вместе с проектом — app/actualize_script.php, запускаемого через cron.
sudo crontab -u www-data -eДобавьте одну строку:
*/20 * * * * php /srv/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1Двадцать минут — разумный интервал, однако интервал обновления каждой отдельной ленты всё равно учитывается: по умолчанию он составляет один час, а для отдельных лент можно задать значение до пятнадцати минут. Сначала запустите скрипт вручную:
sudo -u www-data php /srv/freshrss/app/actualize_script.phpПри нормальной работе выводится отчет о выполнении обновления, и процесс завершается без ошибок PHP; названия лент отображаются при добавлении или обновлении статей. Если вывод пуст, проверьте вывод ошибок PHP и логи FreshRSS; отсутствие сообщений не означает, что проблема в пользователе, от имени которого запущен cron. Ошибка прав доступа к data/ требует проверки владельца и прав на запись.
Добавление первых лент
Используйте кнопку с плюсом в левом верхнем углу интерфейса, вставьте адрес сайта, и FreshRSS автоматически обнаружит ссылку на ленту. Большинство сайтов публикуют её, даже если не рекламируют это явно; обычно она находится по адресам /feed, /rss или /atom.xml. Категории представляют собой папки, и перемещение ленты между ними осуществляется перетаскиванием.
Если вы переходите с другого агрегатора, экспортируйте там файл OPML и импортируйте его на странице управления подписками. OPML (outline processor markup language) — это стандартный формат списка лент, который поддерживает любой достойный внимания агрегатор. При первом обновлении большой импортированный список будет обрабатываться медленно, так как каждая лента запрашивается по одному разу. Дайте первому запуску cron время на выполнение, прежде чем оценивать скорость работы.
Чтение на мобильном устройстве
FreshRSS поддерживает API Google Reader, с которым совместимо множество RSS-приложений. Должны быть выполнены два условия. В настройках аутентификации необходимо включить параметр "Allow API access", что уже было сделано с помощью флага --api-enabled выше. В профиле пользователя должно быть задано значение в поле API password; оно намеренно отделено от основного пароля, так как мобильное устройство легче потерять.
Перейдите по адресу https://rss.example.com/api/, чтобы автоматически запустить проверку конфигурации сервера. Исправная установка возвращает PASS. Если проверка завершается ошибкой, проверьте настройку AllowEncodedSlashes On виртуального хоста и текст ошибки. В приложении укажите адрес сервера как https://rss.example.com/api/greader.php, имя пользователя — ваш логин в FreshRSS, а в качестве пароля — ваш API password.
Альтернатива с использованием Docker
Если вы не хотите обслуживать PHP и Apache вручную, проект предоставляет официальный образ freshrss/freshrss, а один файл compose позволяет развернуть приложение вместе с базой данных. Компромисс стандартный: меньше компонентов на хосте, но появляется дополнительный уровень для отладки в случае сбоев, а для TLS (transport layer security) по-прежнему требуется reverse proxy. Если этот вариант вам подходит больше, в основах Docker Compose для VPS описан формат файла, а строка cron принимает вид docker exec --user www-data freshrss php ./app/actualize_script.php.
Резервное копирование и обновление
Ваше состояние сохраняется в двух местах: в базе данных и в /srv/freshrss/data/. Создайте дамп первой с помощью sudo mysqldump freshrss > freshrss.sql, скопируйте второе и храните обе части вне этого сервера. Также полезно периодически экспортировать список подписок в формате OPML, так как этот файл позволяет перенести список лент в другие программы для чтения, поддерживающие OPML. Он не сохраняет специфические настройки FreshRSS, такие как частота обновления, учетные данные, user agent или правила веб-скрейпинга XPath; для их сохранения используйте экспорт SQLite.
Обновление заключается в распаковке новой версии поверх существующего каталога и повторном выполнении команд смены владельца. Следуйте пути обновления от версии к версии, рекомендованному проектом, и проверяйте работу FreshRSS после каждого шага. FreshRSS применяет миграции базы данных автоматически при следующей загрузке страницы. Сначала сделайте резервную копию, так как неудачная миграция базы данных, которую невозможно восстановить, приведет к потере данных. Если вы устанавливали программу из старого архива, например 1.29.1, переходите на 1.30.4: релизы безопасности 1.30.x включают ротацию ID сессий при изменении аутентификации и ограничения на импорт ZIP-файлов, а версия 1.30.4 также обновляет альтернативные образы Alpine Docker для устранения критических уязвимостей PHP. Программа для чтения лент — это сервис с низким уровнем риска, который отлично подходит в качестве первого проекта, если вы изучаете список того, что стоит размещать на собственном сервере.
FAQ
Почему мои ленты обновляются только при открытии FreshRSS?
Открытие страницы не запускает планировщик получения лент; если планировщик не настроен, используйте ссылку обновления для ручного запуска. Добавьте строку cron, вызывающую app/actualize_script.php от имени пользователя www-data, затем запустите скрипт вручную один раз и изучите вывод. Если вывод пуст, проверьте журнал ошибок PHP и журналы FreshRSS, а затем убедитесь, что у пользователя cron есть права на запись в data/.
Мобильное приложение не подключается, хотя сайт работает. Почему?
API Google Reader использует закодированные косые черты (%2F) в путях запросов, которые Apache по умолчанию отклоняет. Добавьте AllowEncodedSlashes On в конфигурацию виртуального хоста и перезагрузите Apache. Проверьте результат, открыв https://rss.example.com/api/: автоматическая проверка конфигурации должна сообщить о PASS. Также убедитесь, что в профиле задан пароль API, так как он отличается от пароля для входа в систему.
Что выбрать: SQLite или MariaDB?
Для SQLite требуется расширение php-sqlite3, но не нужен сервер баз данных или управление паролями к ним. Для каждого пользователя создается отдельный файл базы данных SQLite, поэтому добавление второго пользователя не вызывает конфликтов при работе с общим файлом и не требует MariaDB. Используйте MariaDB, если вы планируете задействовать сервер баз данных в составе вашего стека LAMP. Переход между ними возможен позже с помощью команд экспорта и импорта, поэтому это решение не является окончательным.
Установщик выдает ошибку при записи конфигурации. В чем причина?
PHP работает от имени www-data в среде Apache, и этот пользователь не имеет прав на запись в директорию, принадлежащую root. Повторно выполните sudo chown -R www-data:www-data /srv/freshrss и sudo chmod -R g+w /srv/freshrss/data, затем снова запустите установщик. Если вы уже запускали установщик из командной строки от имени root, исправьте владельца файлов, созданных в data/, перед повторной попыткой.
Какие требования к серверу для self-hosted RSS-ридера?
Минимальные. FreshRSS спроектирован для работы на скромном оборудовании, но потребление ресурсов зависит от количества лент, размера статей и настроек хранения. Объем дискового пространства растет вместе с архивом, поэтому настройте политику очистки статей в параметрах архивирования, вместо того чтобы хранить всё бесконечно.