SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor

Jak zainstalować FreshRSS na własnym serwerze VPS

Instrukcja instalacji FreshRSS na Ubuntu 24.04 z Apache, PHP 8.3 i MariaDB. Dowiedz się, jak poprawnie skonfigurować zadania cron, uprawnienia plików oraz API dla aplikacji mobilnych.

Co budujesz

Własny czytnik RSS to aplikacja działająca na serwerze, którego jesteś właścicielem. Dzięki temu nikt nie może go wyłączyć ani zmienić wyświetlanych treści. Ten przewodnik opisuje instalację FreshRSS na VPS z systemem Ubuntu 24.04: Apache jako serwer frontowy, PHP jako backend, MariaDB do przechowywania danych oraz zadanie cron pobierające nowe artykuły. RSS (Really Simple Syndication) to format pliku publikowany przez witryny, umożliwiający oprogramowaniu odczyt artykułów. FreshRSS to aplikacja PHP, która gromadzi te pliki, przechowuje artykuły i udostępnia interfejs WWW oraz API (Application Programming Interface) obsługiwane przez aplikacje mobilne.

Sama instalacja jest niewielka: rozpakowanie wydania, utworzenie bazy danych, przygotowanie pliku virtual host, uruchomienie instalatora wiersza poleceń, a następnie utworzenie konta za pomocą cli/create-user.php. Większość poniższych prac dotyczy etapów, w których często popełniane są błędy: konfiguracji zadania odświeżania, kodowania ukośników dla API mobilnego oraz uprawnień do plików.

FreshRSS 1.30.4, opublikowany 21 października 2026 r., jest aktualnym wydaniem na dzień 29 października 2026 r. i wymaga PHP 8.1 lub nowszego. Ubuntu 24.04 dostarcza PHP 8.3, więc pakiety dystrybucyjne są wystarczające i nie ma potrzeby korzystania z zewnętrznych repozytoriów PHP.

Rozpoczęcie od działającego stosu LAMP

FreshRSS jest standardową aplikacją PHP, dlatego wymaga takiego samego środowiska bazowego jak każda inna. Jeśli to środowisko nie zostało jeszcze przygotowane, należy najpierw wykonać konfigurację stosu LAMP dla Ubuntu 24.04, a następnie powrócić do tego miejsca. Wersja skrócona:

sudo apt update
sudo apt install -y apache2 mariadb-server php libapache2-mod-php
sudo systemctl enable --now apache2 mariadb

systemctl status apache2 powinno zwrócić active (running). Jeśli Apache nie uruchamia się, najczęstszą przyczyną jest inny proces zajmujący port 80, a sudo ss -ltnp | grep :80 wskaże jego nazwę.

Rozszerzenia PHP wymagane przez FreshRSS

FreshRSS wymaga obecności bibliotek libxml, cURL, JSON, PDO_MySQL, PCRE oraz ctype. Wymaga również mbstring, iconv, Zlib, ZipArchive, a w systemach 32-bitowych także GMP. W systemie Ubuntu pakiety te są dostępne w oficjalnych repozytoriach:

sudo apt install -y php-curl php-mbstring php-xml php-zip php-mysql php-intl php-gmp
sudo systemctl restart apache2

Sprawdź, które rozszerzenia PHP zostały załadowane, używając polecenia php -m. Brakujące rozszerzenie nie blokuje uruchomienia instalatora. Powoduje ono zatrzymanie procesu na ekranie wymagań z czerwonym komunikatem wskazującym nazwę brakującego elementu. Jest to nieczytelny sposób diagnozy, dlatego warto zweryfikować stan przed rozpoczęciem instalacji. Restart serwera Apache jest konieczny, ponieważ libapache2-mod-php utrzymuje PHP wewnątrz procesu Apache, co sprawia, że nowo zainstalowane rozszerzenie pozostaje niewidoczne dla serwera WWW do momentu jego ponownego uruchomienia.

Pobieranie wydania

Zainstaluj FreshRSS poza domyślnym katalogiem głównym serwera WWW i skieruj na niego konfigurację Apache. Przechowywanie katalogu aplikacji oddzielnie od document root sprawia, że przez HTTP dostępny jest wyłącznie folder 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

Teraz uprawnienia, w kwestii których dokumentacja FreshRSS jest rygorystyczna: użytkownik serwera WWW musi być właścicielem drzewa katalogów, grupa musi mieć uprawnienia do odczytu wszystkich plików, a grupa musi mieć możliwość zapisu do ./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

Pominięcie tego kroku spowoduje błąd instalatora podczas zapisu konfiguracji, ponieważ PHP działa jako www-data, a www-data nie posiada uprawnień do zapisu w katalogu należącym do root.

Tworzenie bazy danych

FreshRSS obsługuje SQLite, MariaDB, MySQL oraz PostgreSQL. SQLite wymaga rozszerzenia php-sqlite3, lecz nie wymaga konfiguracji serwera bazy danych i przechowuje dane każdego użytkownika w osobnym pliku data/users/_user_/db.sqlite. Dodawanie użytkowników nie powoduje zapisywania ich danych w jednym współdzielonym pliku SQLite; niniejszy przewodnik wykorzystuje MariaDB jako element stosu 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;"

Należy użyć utf8mb4, a nie utf8. Kanały informacyjne zawierają emoji oraz znaki spoza alfabetu łacińskiego, a stare trzybajtowe kodowanie utf8 nie pozwala na zapis znaków czterobajtowych. Nieobsługiwane znaki powodują błąd w domyślnym trybie ścisłym MariaDB; obcinanie danych zależy od trybu SQL oraz opcji instrukcji, takich jak IGNORE.

Wirtualny host Apache

Katalog publiczny to p/, a nie najwyższy poziom drzewa katalogów. Cała reszta, w tym plik konfiguracyjny zawierający hasło do bazy danych, znajduje się powyżej katalogu głównego dokumentów, skąd Apache nigdy nie udostępni plików.

<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>

Zapisz to jako /etc/apache2/sites-available/freshrss.conf i aktywuj konfigurację:

sudo a2enmod rewrite
sudo a2ensite freshrss
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2

configtest powinno zwrócić Syntax OK. Dyrektywa AllowEncodedSlashes On wydaje się opcjonalna, lecz w rzeczywistości taka nie jest: API Google Reader wysyła identyfikatory kanałów zawierające %2F. Bez tej dyrektywy Apache odrzuca takie żądania, co powoduje, że aplikacje mobilne nie synchronizują danych, podczas gdy interfejs WWW działa poprawnie.

Dodaj HTTPS przed zalogowaniem

Wprowadzisz hasło w tej witrynie, więc najpierw uzyskaj certyfikat. Skieruj rekord A na serwer, a następnie wykonaj konfigurację Certbot dla Apache na Ubuntu i uruchom sudo certbot --apache -d rss.example.com. Certbot zmodyfikuje wirtualny host dla portu 443 i doda przekierowanie. Potwierdź działanie za pomocą curl -I https://rss.example.com/, co powinno zwrócić 200 lub przekierowanie do strony logowania.

Uruchomienie instalatora z poziomu wiersza poleceń

FreshRSS posiada instalator przeglądarkowy, jednak wersja wiersza poleceń jest powtarzalna i pozwala zachować dokładny zapis dokonanych wyborów.

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'

Oba polecenia należy uruchomić jako www-data. Uruchomienie ich z uprawnieniami root powoduje, że pliki konfiguracyjne stają się własnością użytkownika root, co uniemożliwia późniejszy zapis ustawień przez interfejs WWW. Parametr --environment production jest również istotny, ponieważ ustawienie deweloperskie powoduje wyświetlanie powiadomień PHP na stronie.

Załaduj https://rss.example.com/ i zaloguj się jako admin.

Dlaczego kanały nie odświeżają się automatycznie

Żaden proces nie pobiera kanałów, dopóki nie zostanie to skonfigurowane. Otwarcie FreshRSS nie uruchamia harmonogramu pobierania; bez skonfigurowanego harmonogramu należy używać linku aktualizacji w menu nawigacyjnym, aby pobierać artykuły ręcznie. Rozwiązaniem jest skrypt dostarczany wraz z projektem, app/actualize_script.php, uruchamiany za pomocą cron.

sudo crontab -u www-data -e

Dodaj jeden wiersz:

*/20 * * * * php /srv/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1

Dwadzieścia minut to rozsądny harmonogram, jednak nadal obowiązuje interwał odświeżania każdego kanału: domyślnie jest to jedna godzina, a poszczególne kanały obsługują interwały nawet do piętnastu minut. Najpierw uruchom skrypt ręcznie:

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

Poprawne wyjście informuje o przebiegu odświeżania i kończy się bez błędu PHP; nazwy kanałów pojawiają się w momencie dodania lub aktualizacji artykułów. Jeśli skrypt nie zwraca żadnych informacji, sprawdź wyjście błędów PHP oraz logi FreshRSS; sam brak komunikatów nie wskazuje na użytkownika cron jako przyczynę problemu. Błąd uprawnień w data/ wymaga sprawdzenia właściciela oraz uprawnień do zapisu.

Dodawanie pierwszych kanałów

Użyj przycisku plusa w lewym górnym rogu interfejsu, wklej adres strony, a FreshRSS automatycznie wykryje link do kanału. Większość witryn publikuje kanał, nawet jeśli nie jest on jawnie promowany; zazwyczaj znajduje się on pod adresem /feed, /rss lub /atom.xml. Kategorie pełnią funkcję folderów, a przenoszenie między nimi kanałów odbywa się metodą przeciągnij i upuść.

W przypadku migracji z innego czytnika, wyeksportuj plik OPML z poprzedniego narzędzia i zaimportuj go na stronie zarządzania subskrypcjami. OPML (outline processor markup language) to standardowy format listy kanałów, obsługiwany przez każdy czytnik godny uwagi. Import dużej liczby subskrypcji powoduje spowolnienie przy pierwszym odświeżeniu, ponieważ każdy kanał jest pobierany jednorazowo. Przed oceną wydajności należy pozwolić na zakończenie pierwszego uruchomienia zadania cron.

Odczyt na urządzeniu mobilnym

FreshRSS obsługuje API Google Reader, z którym współpracuje wiele aplikacji RSS. Należy spełnić dwa warunki. W ustawieniach uwierzytelniania musi być włączona opcja "Allow API access", co zostało już skonfigurowane za pomocą flagi --api-enabled powyżej. W profilu użytkownika pole API password musi zawierać wartość. Jest ono celowo oddzielone od hasła logowania, ponieważ urządzenie mobilne łatwiej zgubić.

Odwiedź https://rss.example.com/api/, aby automatycznie uruchomić testy konfiguracji serwera. Poprawna konfiguracja zwraca PASS. Jeśli test zakończy się niepowodzeniem, sprawdź ustawienie AllowEncodedSlashes On wirtualnego hosta oraz zgłoszony błąd. W aplikacji jako adres serwera podaj https://rss.example.com/api/greader.php, jako nazwę użytkownika wpisz swojego użytkownika FreshRSS, a jako hasło użyj hasła API.

Alternatywa w postaci Docker

Jeśli użytkownik woli nie zarządzać ręcznie PHP oraz Apache, projekt udostępnia oficjalny obraz freshrss/freshrss, a jeden plik compose pozwala uruchomić aplikację wraz z bazą danych. Wiąże się to z typowym kompromisem: mniej komponentów na hoście, ale dodatkowa warstwa do debugowania w razie awarii, przy czym nadal wymagany jest reverse proxy do obsługi TLS (transport layer security). Jeśli takie rozwiązanie jest bardziej odpowiednie, podstawy Docker Compose na VPS opisują format pliku, a wpis w cron zmienia się na docker exec --user www-data freshrss php ./app/actualize_script.php.

Kopie zapasowe i aktualizacje

Stan aplikacji przechowują dwa elementy: baza danych oraz /srv/freshrss/data/. Wykonaj zrzut pierwszej za pomocą sudo mysqldump freshrss > freshrss.sql, skopiuj drugi element i przechowuj obie kopie poza tym serwerem. Warto również okresowo eksportować listę subskrypcji do formatu OPML, ponieważ plik ten pozwala przenieść listę kanałów do innych czytników obsługujących OPML. Nie zachowuje on jednak ustawień specyficznych dla FreshRSS, takich jak częstotliwość odświeżania, dane uwierzytelniające, user agent czy reguły web scrapingu XPath; aby je zachować, należy użyć eksportu SQLite.

Aktualizacja polega na rozpakowaniu nowszego wydania w tym samym katalogu i ponownym wykonaniu poleceń nadających uprawnienia. Należy postępować zgodnie ze ścieżką aktualizacji wersja po wersji zalecaną przez projekt i weryfikować działanie FreshRSS po każdym kroku. FreshRSS automatycznie przeprowadza migrację bazy danych przy kolejnym załadowaniu strony. Przed przystąpieniem do prac należy wykonać kopię zapasową, ponieważ nieudana migracja na bazie danych, której nie można przywrócić, prowadzi do utraty danych. W przypadku instalacji ze starszego archiwum, na przykład 1.29.1, należy przejść do 1.30.4: wydania z serii 1.30.x wprowadzają rotację identyfikatorów sesji przy zmianach uwierzytelniania oraz limity dla importów ZIP, natomiast wersja 1.30.4 aktualizuje również alternatywne obrazy Alpine Docker w celu usunięcia krytycznych luk w PHP. Czytnik RSS to usługa o niskim poziomie ryzyka i dobry kandydat na początek, jeśli realizujesz listę usług wartych samodzielnego hostowania.

FAQ

Dlaczego moje kanały aktualizują się tylko po otwarciu FreshRSS?

Otwarcie strony nie uruchamia harmonogramu pobierania kanałów; bez skonfigurowanego harmonogramu należy używać linku aktualizacji w celu ręcznego odświeżenia. Dodaj wpis cron wywołujący app/actualize_script.php jako użytkownik www-data, a następnie uruchom skrypt ręcznie i sprawdź jego wynik. Jeśli skrypt nie zwraca żadnych komunikatów, sprawdź logi błędów PHP oraz logi FreshRSS, a następnie zweryfikuj, czy użytkownik cron posiada uprawnienia do zapisu w data/.

Moja aplikacja mobilna nie może się połączyć, mimo że strona działa. Dlaczego?

API Google Reader umieszcza zakodowane ukośniki (%2F) w ścieżkach żądań, a Apache domyślnie je odrzuca. Dodaj AllowEncodedSlashes On wewnątrz konfiguracji wirtualnego hosta i przeładuj Apache. Potwierdź poprawkę, otwierając https://rss.example.com/api/, gdzie automatyczna kontrola konfiguracji powinna zgłosić PASS. Sprawdź również, czy hasło do API zostało ustawione w profilu użytkownika, ponieważ jest ono niezależne od hasła logowania.

Czy powinienem użyć SQLite czy MariaDB?

SQLite wymaga rozszerzenia php-sqlite3, ale nie potrzebuje serwera bazy danych ani zarządzania hasłami do bazy. Każdy użytkownik otrzymuje osobny plik bazy danych SQLite, więc dodanie kolejnego użytkownika nie powoduje konfliktów w jednym współdzielonym pliku ani nie wymaga MariaDB. Użyj MariaDB, jeśli chcesz wykorzystać serwer bazy danych w swoim stosie LAMP. Późniejsza migracja między tymi rozwiązaniami jest możliwa za pomocą poleceń eksportu i importu, więc nie jest to decyzja ostateczna.

Instalator kończy się błędem podczas zapisu konfiguracji. Co jest nie tak?

PHP działa jako www-data w środowisku Apache, a ten użytkownik nie ma uprawnień do zapisu w katalogu należącym do root. Uruchom ponownie sudo chown -R www-data:www-data /srv/freshrss oraz sudo chmod -R g+w /srv/freshrss/data, a następnie ponownie uruchom instalator. Jeśli instalator wiersza poleceń został już uruchomiony z uprawnieniami root, popraw właściciela plików utworzonych w data/ przed ponowną próbą.

Jakich zasobów serwera wymaga samodzielnie hostowany czytnik RSS?

Bardzo niewielkich. FreshRSS jest zaprojektowany do działania na skromnym sprzęcie, jednak zużycie zasobów zależy od liczby kanałów, rozmiaru artykułów oraz ustawień retencji. Zajętość dysku rośnie wraz z okresem przechowywania danych, dlatego należy ustawić politykę usuwania artykułów w ustawieniach archiwizacji, zamiast przechowywać wszystko w nieskończoność.

Czy ten artykuł był przydatny?