SSD Nodes Learn 8GB RAM — $66/рік
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-01

Як встановити FreshRSS на VPS з Ubuntu 24.04

Покроково встановіть FreshRSS 1.29.1 на VPS з Ubuntu 24.04: Apache, PHP 8.3, MariaDB, cron для оновлення стрічок і API для мобільного застосунку.

Що ви налаштовуєте

RSS-рідер із власним хостингом — це програма для читання стрічок, яка працює на сервері, що належить вам. Тому ніхто не може вимкнути її або змінити вміст, який вона вам показує. У цьому посібнику FreshRSS встановлюється на VPS з Ubuntu 24.04: Apache працює як зовнішній вебсервер, PHP — за ним, MariaDB використовується для зберігання даних, а одне завдання cron отримує нові статті. RSS (really simple syndication) — це формат файлів, які сайт публікує, щоб програми могли читати його статті. FreshRSS — це застосунок PHP, який збирає ці файли, зберігає статті та надає вебінтерфейс і API (application programming interface), з яким взаємодіють мобільні застосунки.

Саме встановлення нескладне: розпакувати реліз, створити базу даних, налаштувати один віртуальний хост і виконати одну команду інсталятора в командному рядку. Більшість наведених нижче дій стосується проблем, які часто виникають після встановлення: налаштування завдання оновлення, закодовані косі риски для мобільного API та права власника файлів.

FreshRSS 1.29.1 — поточний реліз станом на July 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 mariadb

systemctl 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 буде доступна лише загальнодоступна папка.

cd /tmp
curl -fsSLO https://github.com/FreshRSS/FreshRSS/archive/refs/tags/1.29.1.tar.gz
tar xzf 1.29.1.tar.gz
sudo mv FreshRSS-1.29.1 /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 не потребує налаштування та підходить для однієї людини з кількома сотнями стрічок. Якщо один екземпляр використовують кілька людей, краще вибрати MariaDB, оскільки паралельні записи завдання оновлення та вебінтерфейсу більше не конкурують за блокування одного файлу.

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. Стрічки містять emoji та нелатинські системи письма, а старе трьохбайтове кодування utf8 обрізає заголовок статті на першому символі, що займає чотири байти.

Віртуальний хост Apache

Загальнодоступний каталог — це p/, а не верхній рівень дерева каталогів. Усе інше, зокрема файл конфігурації, що містить пароль до бази даних, розташовано вище кореневого каталогу документів. 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 apache2

Команда configtest має вивести 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

Двадцять хвилин — практичний мінімум. Скрипт не оновлює окрему стрічку частіше ніж раз на двадцять хвилин. Тому коротший інтервал лише витрачає ресурси CPU. Спочатку запустіть його вручну:

sudo -u www-data php /srv/freshrss/app/actualize_script.php

За нормальної роботи у виводі назви кожної отриманої стрічки, а завершення відбувається без помилки PHP. Якщо скрипт взагалі нічого не виводить, указано неправильного користувача cron. Помилка доступу до data/ означає, що крок chmod -R g+w пропущено.

Додайте перші стрічки

Натисніть кнопку з плюсом у лівому верхньому куті інтерфейсу, вставте адресу сайту, і FreshRSS автоматично знайде посилання на стрічку. Більшість сайтів досі публікують стрічку, навіть якщо не вказують її явно. Зазвичай вона доступна за адресою /feed, /rss або /atom.xml. Категорії є папками, а переміщення стрічки між ними виконується перетягуванням.

Якщо ви переходите з іншого reader, експортуйте там файл OPML та імпортуйте його на сторінці керування підписками. OPML (outline processor markup language) — стандартний формат списку стрічок. Його підтримує кожен reader, з якого варто переходити. Великий імпорт повільно обробляється під час першого оновлення, оскільки кожна стрічка завантажується один раз. Тому зачекайте завершення першого запуску cron, перш ніж оцінювати швидкість.

Читайте на телефоні

FreshRSS підтримує Google Reader API, який підтримує майже кожна програма для RSS. Має виконуватися 2 умови. У налаштуваннях автентифікації параметр "Allow API access" має бути увімкнено. Прапорець --api-enabled вище вже встановив цей параметр. У профілі поле пароля API має містити значення. Цей пароль навмисно відокремлено від пароля для входу, оскільки телефон легше загубити.

Відкрийте https://rss.example.com/api/ і виберіть "Check full server configuration". У робочій конфігурації повертається PASS. Причиною помилки майже завжди є відсутній рядок AllowEncodedSlashes On. У програмі вкажіть адресу сервера як https://rss.example.com/api/greader.php, ім’я користувача — як ім’я користувача FreshRSS, а пароль API — як пароль.

Альтернатива Docker

Якщо ви не хочете самостійно обслуговувати PHP і Apache, проєкт публікує офіційний образ freshrss/freshrss. Один файл compose запускає застосунок і його базу даних разом. Компроміс стандартний: на хості менше компонентів, але в разі несправності потрібно налагоджувати ще один рівень. Для TLS (захисту транспортного рівня) все одно потрібен зворотний проксі. Якщо цей варіант вам більше підходить, основи Docker Compose для VPS описують формат файлу, а рядок cron матиме вигляд docker exec --user www-data freshrss php ./app/actualize_script.php.

Резервні копії та оновлення

Ваш стан зберігається у двох місцях: у базі даних і в /srv/freshrss/data/. Створіть дамп бази даних за допомогою sudo mysqldump freshrss > freshrss.sql, скопіюйте /srv/freshrss/data/ і зберігайте обидві копії не на цьому сервері. Список підписок також варто час від часу експортувати у формат OPML, оскільки цей файл дає змогу відновити налаштування читання в будь-якому програмному забезпеченні для RSS.

Оновлення полягає в розпакуванні новішого випуску в той самий каталог і повторному виконанні команд для налаштування власника. Під час наступного завантаження сторінки FreshRSS автоматично застосує міграції бази даних. Спочатку створіть резервну копію, оскільки невдала міграція бази даних, яку неможливо відновити, призведе до незворотної втрати. Читач RSS — це сервіс із низьким ризиком під час експлуатації та вдалий перший кандидат, якщо ви опрацьовуєте список того, що варто розміщувати на власному сервері.

FAQ

Чому мої стрічки оновлюються лише після відкриття FreshRSS?

Тому що планувальника немає, доки ви його не створите. FreshRSS оновлює стрічки, коли відкрито сеанс у браузері, і не виконує жодних дій після закриття вкладки. Додайте рядок cron, який викликає app/actualize_script.php від імені користувача www-data, потім один раз запустіть скрипт вручну та перегляньте його вивід. Відсутність виводу зазвичай означає, що cron запускає скрипт від імені неправильного користувача, тому PHP не може записати дані до data/.

Мобільний застосунок не може підключитися, але вебсайт працює. Чому?

Google Reader API передає кодовані косі риски (%2F) у шляхах запитів, а Apache типово відхиляє такі запити. Додайте AllowEncodedSlashes On у віртуальний хост і перезавантажте Apache. Перевірте виправлення, відкривши https://rss.example.com/api/ і запустивши "Check full server configuration". У результаті має бути повідомлення PASS. Також перевірте, чи задано пароль API у вашому профілі, оскільки він відрізняється від пароля для входу.

Що вибрати: SQLite чи MariaDB?

SQLite підходить для одного користувача, оскільки нічого не потрібно встановлювати й не потрібно керувати паролем. MariaDB варто використовувати, коли екземпляром користуються кілька людей або коли кількість стрічок перевищує кілька сотень. Це пов’язано з тим, що завдання оновлення та вебінтерфейс записують дані одночасно, а блокування одного файла стає обмеженням. Пізніше можна перенести дані між цими системами за допомогою команд експорту та імпорту, тому це рішення не є остаточним.

Інсталятор не може записати конфігурацію. У чому проблема?

Apache запускає PHP від імені www-data, а цей користувач не може записувати до каталогу, власником якого є root. Повторно виконайте sudo chown -R www-data:www-data /srv/freshrss і sudo chmod -R g+w /srv/freshrss/data, а потім знову запустіть інсталятор. Якщо ви вже запускали інсталятор командного рядка від імені root, видаліть файли, створені ним у data/, перш ніж повторити спробу. Проблема полягає саме у власності цих файлів.

Які ресурси сервера потрібні для власного RSS-читача?

Дуже невеликі. Кілька сотень стрічок без проблем працюватимуть на невеликому тарифному плані, оскільки навантаження складається з коротких періодів отримання даних через HTTP кожні двадцять хвилин, а база даних залишається невеликою після видалення старих статей. Обсяг диска зростає залежно від періоду зберігання, тому в параметрах архівування задайте політику видалення статей, а не зберігайте все безстроково.

#freshrss#rss#self-hosting#php#apache