FreshRSS installeren op een Ubuntu VPS met Apache
Installeer FreshRSS 1.29.1 op Ubuntu 24.04 met Apache, PHP 8.3 en MariaDB. Configureer de virtual host, cron-vernieuwing en de mobiele API.
Wat u bouwt
Een zelfgehoste RSS-lezer is een feedlezer die op een server draait die u beheert. Niemand kan deze daarom uitschakelen of wijzigen wat deze aan u toont. In deze handleiding installeert u FreshRSS op een Ubuntu 24.04 VPS: Apache ervoor, PHP erachter, MariaDB voor de opslag en één cron-taak die nieuwe artikelen ophaalt. RSS (really simple syndication) is de bestandsindeling die een website publiceert, zodat software de artikelen kan lezen. FreshRSS is de PHP-toepassing die deze bestanden verzamelt, de artikelen bewaart en een webinterface plus een API (application programming interface) biedt waarmee telefoonapps communiceren.
De installatie zelf is beperkt: pak een release uit, maak een database, schrijf één virtual host en voer één opdrachtregelinstallatie uit. Het meeste werk hieronder betreft zaken die daarna vaak verkeerd worden ingesteld: de taak voor het vernieuwen van feeds, gecodeerde slashes voor de mobiele API en het bestandseigendom.
FreshRSS 1.29.1 is de huidige release van juli 2026 en vereist PHP 8.1 of nieuwer. Ubuntu 24.04 levert PHP 8.3, dus de distributiepakketten volstaan. U hebt geen PHP-repository van een derde partij nodig.
Begin met een werkende LAMP-stack
FreshRSS is een gewone PHP-toepassing en heeft daarom dezelfde basis nodig als elke andere PHP-toepassing. Als u die basis nog niet hebt opgebouwd, volgt u eerst de LAMP-stackconfiguratie voor Ubuntu 24.04 en keert u daarna hier terug. De korte versie:
sudo apt update
sudo apt install -y apache2 mariadb-server php libapache2-mod-php
sudo systemctl enable --now apache2 mariadbsystemctl status apache2 moet active (running) rapporteren. Als Apache niet start, is de gebruikelijke oorzaak dat een ander proces poort 80 al gebruikt. sudo ss -ltnp | grep :80 geeft aan welk proces dat is.
De PHP-extensies die FreshRSS nodig heeft
FreshRSS beschouwt libxml, cURL, JSON, PDO_MySQL, PCRE en ctype als verplicht. Daarnaast heeft het mbstring, iconv, Zlib en ZipArchive nodig, en GMP op een 32-bitsysteem. Op Ubuntu zijn dit distributiepakketten:
sudo apt install -y php-curl php-mbstring php-xml php-zip php-mysql php-intl php-gmp
sudo systemctl restart apache2Controleer met php -m welke PHP-extensies daadwerkelijk zijn geladen. Een ontbrekende extensie voorkomt niet dat het installatieprogramma start. Het installatieprogramma stopt pas op het scherm met de vereisten, met een rode regel waarin de extensie wordt genoemd. Dat is een verwarrende plaats om het probleem te ontdekken. Controleer dit daarom nu. Apache opnieuw starten is belangrijk, omdat libapache2-mod-php PHP binnen het Apache-proces uitvoert. Een nieuw geïnstalleerde extensie is daardoor pas na een herstart zichtbaar voor de webserver.
De release downloaden
Installeer FreshRSS buiten de standaard webroot en laat Apache ernaar verwijzen. Als u de applicatiemap gescheiden houdt van de documentroot, is alleen de openbare map via HTTP bereikbaar.
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/freshrssStel nu de machtigingen in. De FreshRSS-documentatie stelt hiervoor strikte eisen: de webservergebruiker is eigenaar van de volledige structuur, de groep kan elk bestand lezen en de groep kan naar ./data/ schrijven.
sudo chown -R www-data:www-data /srv/freshrss
sudo chmod -R g+r /srv/freshrss
sudo chmod -R g+w /srv/freshrss/dataAls u dit overslaat, mislukt het installatieprogramma bij het schrijven van de configuratie. PHP wordt namelijk uitgevoerd als www-data en www-data kan niet schrijven naar een map waarvan root eigenaar is.
De database aanmaken
FreshRSS ondersteunt SQLite, MariaDB, MySQL en PostgreSQL. SQLite vereist geen configuratie en is geschikt voor één persoon met enkele honderden feeds. MariaDB is de betere keuze zodra meerdere personen de instantie gebruiken, omdat gelijktijdige schrijfbewerkingen van de vernieuwtaak en de webinterface dan niet langer strijden om één bestandsvergrendeling.
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;"Gebruik utf8mb4 en niet utf8. Feeds bevatten emoji en niet-Latijnse scripts. De oude drie-bytecodering utf8 kapt een artikeltitel af bij het eerste teken dat 4 bytes gebruikt.
De virtuele Apache-host
De openbare map is p/, niet de bovenkant van de mappenstructuur. Al het overige, inclusief het configuratiebestand met uw databasewachtwoord, bevindt zich boven de documentroot. Apache zal dat bestand nooit aanbieden.
<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>Sla dit op als /etc/apache2/sites-available/freshrss.conf en schakel het in:
sudo a2enmod rewrite
sudo a2ensite freshrss
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2configtest moet Syntax OK afdrukken. AllowEncodedSlashes On lijkt optioneel, maar is dat niet: de Google Reader API verstuurt feed-id's met %2F. Zonder deze directive weigert Apache deze aanvragen. Mobiele apps kunnen dan niet synchroniseren, terwijl de webinterface wel volledig werkt.
Voeg HTTPS toe voordat u zich aanmeldt
U staat op het punt een wachtwoord op deze site in te voeren. Zorg daarom eerst voor een certificaat. Laat een A-record naar de server verwijzen. Volg daarna de Certbot-configuratie voor Apache op Ubuntu en voer sudo certbot --apache -d rss.example.com uit. Certbot herschrijft de virtual host voor poort 443 en voegt de omleiding toe. Controleer dit met curl -I https://rss.example.com/. Deze opdracht moet een 200 retourneren of naar de aanmeldpagina omleiden.
Voer het installatieprogramma uit vanaf de opdrachtregel
FreshRSS heeft een installatieprogramma voor de browser, maar de versie voor de opdrachtregel is herhaalbaar en legt precies vast welke keuzes u hebt gemaakt.
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'Voer beide uit als www-data. Als u ze als root uitvoert, worden configuratiebestanden aangemaakt die eigendom zijn van root. De webinterface kan instellingen daarna niet meer opslaan. --environment production is ook van belang, omdat de ontwikkelinstelling PHP-meldingen in de pagina afdrukt.
Laad https://rss.example.com/ en meld u aan als admin.
Waarom feeds niet automatisch worden vernieuwd
Er wordt niets opgevraagd totdat u dit instelt. FreshRSS vernieuwt feeds zolang er een browservenster op de toepassing geopend is. Een instantie die u twee keer per dag bezoekt, toont daardoor artikelen die twaalf uur verouderd zijn. Gebruik hiervoor het script dat het project levert, app/actualize_script.php, en voer dit uit vanuit cron.
sudo crontab -u www-data -eVoeg één regel toe:
*/20 * * * * php /srv/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1Twintig minuten is het kortste zinvolle interval. Het script weigert namelijk dezelfde feed vaker dan eenmaal per twintig minuten te vernieuwen. Een korter interval verbruikt alleen onnodig CPU. Voer het script eerst handmatig uit:
sudo -u www-data php /srv/freshrss/app/actualize_script.phpBij een correcte uitvoering wordt de naam van elke opgehaalde feed weergegeven en eindigt de uitvoer zonder PHP-fout. Als er helemaal niets wordt weergegeven, is de cron-gebruiker onjuist. Een toestemmingsfout op data/ betekent dat de stap chmod -R g+w is overgeslagen.
Uw eerste feeds toevoegen
Gebruik de plusknop linksboven in de interface, plak een siteadres en FreshRSS zoekt de feedlink voor u. De meeste sites publiceren er nog steeds een, ook als ze deze niet vermelden. Meestal staat deze op /feed, /rss of /atom.xml. Categorieën zijn mappen. U verplaatst een feed door deze te slepen.
Als u van een andere reader komt, exporteert u daar een OPML-bestand en importeert u dit via de pagina voor abonnementsbeheer. OPML (outline processor markup language) is de standaardindeling voor feedlijsten. Elke reader die het overstappen waard is, ondersteunt deze indeling. Een grote import duurt bij de eerste refresh langer, omdat elke feed eenmaal wordt opgehaald. Geef de eerste cron-run daarom de tijd voordat u de snelheid beoordeelt.
Lees dit op uw telefoon
FreshRSS ondersteunt de Google Reader API, die door vrijwel elke RSS-app wordt ondersteund. Aan twee voorwaarden moet zijn voldaan. In de authenticatie-instellingen moet "Allow API access" zijn ingeschakeld. De bovenstaande --api-enabled-flag heeft dit al ingesteld. In uw profiel moet het veld voor het API-wachtwoord een waarde bevatten. Dit wachtwoord staat bewust los van uw loginwachtwoord, omdat een telefoon gemakkelijker zoekraakt.
Ga naar https://rss.example.com/api/ en kies "Check full server configuration". Een werkende configuratie geeft PASS terug. Als dit mislukt, ontbreekt vrijwel altijd de regel AllowEncodedSlashes On. Geef in de app het serveradres op als https://rss.example.com/api/greader.php, uw FreshRSS-gebruikersnaam als gebruikersnaam en het API-wachtwoord als wachtwoord.
Het Docker-alternatief
Als u PHP en Apache liever niet handmatig beheert, publiceert het project een officiële freshrss/freshrss-image. Met één compose-bestand beschikt u over de applicatie en de bijbehorende database. De gebruikelijke afweging blijft bestaan: minder onderdelen op de host, maar een extra laag die u moet onderzoeken als er iets misgaat. Voor TLS (Transport Layer Security) is nog steeds een reverse proxy nodig. Als dat beter bij u past, behandelen de basisprincipes van Docker Compose voor een VPS de bestandsindeling. De cron-regel wordt dan docker exec --user www-data freshrss php ./app/actualize_script.php.
Back-ups en upgrades
Twee zaken bevatten uw configuratiestatus: de database en /srv/freshrss/data/. Maak van het eerste een dump met sudo mysqldump freshrss > freshrss.sql, kopieer het tweede en bewaar beide buiten deze server. Uw abonnementslijst is ook af en toe een OPML-export waard, omdat u met dat bestand uw leesconfiguratie in elke RSS-software opnieuw kunt opbouwen.
Upgraden betekent een nieuwere release uitpakken over dezelfde directory en de opdrachten voor het instellen van eigenaars opnieuw uitvoeren. FreshRSS voert de eigen databasemigraties uit wanneer de volgende pagina wordt geladen. Maak eerst een back-up, omdat een mislukte migratie op een database die u niet kunt herstellen tot een onherstelbare situatie leidt. Een reader is een service met een laag risico om uit te voeren en een goede eerste kandidaat als u bezig bent met een lijst van wat u zelf kunt hosten.
FAQ
Waarom worden mijn feeds alleen bijgewerkt wanneer ik FreshRSS open?
Omdat er pas een scheduler bestaat wanneer u er een aanmaakt. FreshRSS vernieuwt feeds zolang er een browsersessie open is en doet niets wanneer het tabblad wordt gesloten. Voeg de cron-regel toe die app/actualize_script.php aanroept als gebruiker www-data. Voer het script daarna eenmaal handmatig uit en lees de uitvoer. Geen uitvoer betekent meestal dat cron het script als de verkeerde gebruiker uitvoert. PHP kan dan niet naar data/ schrijven.
Mijn mobiele app kan geen verbinding maken, maar de website werkt wel. Waarom?
De Google Reader API plaatst gecodeerde slashes (%2F) in aanvraagpaden. Apache weigert deze standaard. Voeg AllowEncodedSlashes On toe binnen de virtual host en herlaad Apache. Controleer de oplossing door https://rss.example.com/api/ te openen en "Check full server configuration" uit te voeren. Daar moet PASS worden gemeld. Controleer ook of het API-wachtwoord in uw profiel is ingesteld. Dit wachtwoord staat los van uw inlogwachtwoord.
Moet ik SQLite of MariaDB gebruiken?
Gebruik SQLite voor één gebruiker. Er hoeft dan niets te worden geïnstalleerd en u hoeft geen wachtwoord te beheren. Gebruik MariaDB zodra meer dan één persoon de instance gebruikt of zodra u enkele honderden feeds hebt. De refresh-taak en de webinterface schrijven dan tegelijkertijd. Eén bestandsvergrendeling wordt dan de beperking. Later kunt u tussen beide systemen migreren met de export- en importopdrachten. Dit is dus geen permanente keuze.
De installer mislukt bij het schrijven van de configuratie. Wat is er mis?
PHP wordt onder Apache uitgevoerd als www-data. Deze gebruiker kan niet schrijven naar een directory die eigendom is van root. Voer sudo chown -R www-data:www-data /srv/freshrss en sudo chmod -R g+w /srv/freshrss/data opnieuw uit en start de installer daarna opnieuw. Als u de opdrachtregelinstaller al als root hebt uitgevoerd, verwijdert u vóór de nieuwe poging de bestanden die deze onder data/ heeft aangemaakt. De eigendom van deze bestanden is het werkelijke probleem.
Hoeveel servercapaciteit heeft een zelf gehoste RSS-reader nodig?
Zeer weinig. Enkele honderden feeds op een klein plan vormen geen probleem. De belasting bestaat uit korte pieken bij het ophalen van HTTP-inhoud om de twintig minuten. De database blijft klein zodra oude artikelen zijn verwijderd. Het schijfgebruik neemt toe met de bewaartermijn. Stel daarom een beleid voor het verwijderen van artikelen in bij de archiveringsinstellingen, in plaats van alles onbeperkt te bewaren.