SSD Nodes Learn Hosting plans →
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-08-07

FreshRSS installeren op Ubuntu VPS: stap voor stap

Installeer FreshRSS op uw eigen Ubuntu 24.04 server met Apache, PHP 8.3 en MariaDB. Leer hoe u de virtual host configureert, cron jobs instelt en de mobiele API werkend krijgt.

Wat u bouwt

Een zelfgehoste RSS-lezer is een feed-lezer die draait op een server die uw eigendom is, zodat niemand deze kan afsluiten of kan bepalen wat u te zien krijgt. Deze handleiding installeert FreshRSS op een Ubuntu 24.04 VPS: Apache aan de voorzijde, PHP op de achtergrond, MariaDB voor opslag en één cron job die nieuwe artikelen ophaalt. RSS (Really Simple Syndication) is het bestandsformaat dat een website publiceert zodat software de artikelen kan lezen. FreshRSS is de PHP-applicatie die deze bestanden verzamelt, de artikelen bewaart en u een webinterface biedt, plus een API (Application Programming Interface) waar mobiele apps mee communiceren.

De installatie zelf is beperkt: pak een release uit, maak een database aan, schrijf één virtual host en voer één command-line installer uit. Het meeste werk hieronder betreft de zaken die achteraf vaak fout gaan, zoals de verversingstaak, gecodeerde slashes voor de mobiele API en bestandsrechten.

FreshRSS 1.29.1 is de huidige release per juli 2026 en vereist PHP 8.1 of nieuwer. Ubuntu 24.04 levert PHP 8.3, dus de distributiepakketten volstaan en u heeft geen PHP-repository van derden nodig.

Beginnen met een werkende LAMP-stack

FreshRSS is een standaard PHP-applicatie en vereist daarom dezelfde basis als elke andere applicatie. Als u deze basis nog niet heeft opgezet, volg dan eerst de handleiding voor het opzetten van een LAMP-stack op Ubuntu 24.04 en keer 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 mariadb

systemctl status apache2 hoort active (running) te rapporteren. Als Apache niet wil starten, is de gebruikelijke oorzaak dat een ander proces poort 80 al bezet houdt; sudo ss -ltnp | grep :80 geeft aan welk proces dit is.

De PHP-extensies die FreshRSS vereist

FreshRSS beschouwt libxml, cURL, JSON, PDO_MySQL, PCRE en ctype als verplicht. Daarnaast zijn mbstring, iconv, Zlib, ZipArchive en op 32-bit systemen ook GMP vereist. Op Ubuntu zijn deze beschikbaar als distributiepakketten:

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

Controleer welke extensies PHP daadwerkelijk heeft geladen met php -m. Een ontbrekende extensie voorkomt niet dat het installatieprogramma start. Het proces stopt echter bij het vereistenscherm met een rode regel die de naam van de extensie vermeldt; dit is een onduidelijk moment om het probleem te ontdekken, dus controleer dit vooraf. Het herstarten van Apache is noodzakelijk omdat libapache2-mod-php PHP binnen het Apache-proces houdt, waardoor een zojuist geïnstalleerde extensie onzichtbaar blijft voor de webserver totdat deze opnieuw wordt opgestart.

De release downloaden

Installeer FreshRSS buiten de standaard web-root en verwijs Apache hiernaar. Door de applicatiemap gescheiden te houden van de document-root, is alleen de map p 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/freshrss

Stel nu de rechten in, waar de documentatie van FreshRSS strikt in is: de gebruiker van de webserver is eigenaar van de boomstructuur, de groep kan elk bestand lezen en de groep kan schrijven naar ./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

Sla dit niet over, anders mislukt de installatie bij het schrijven van de configuratie. Dit gebeurt omdat PHP wordt uitgevoerd als www-data en www-data niet kan schrijven in een map waarvan root de eigenaar is.

De database aanmaken

FreshRSS ondersteunt SQLite, MariaDB, MySQL en PostgreSQL. SQLite vereist geen configuratie en is geschikt voor één gebruiker met enkele honderden feeds. MariaDB is de betere keuze zodra meerdere personen de instantie delen, omdat gelijktijdige schrijfacties van de ververstaak en de webinterface dan niet langer strijden om een enkele 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 tekens, en de oude drie-byte utf8-codering kapt een artikeltitel af bij het eerste vier-byte teken.

De Apache virtual host

De publieke map is p/, niet de bovenkant van de mappenstructuur. Al het overige, inclusief het configuratiebestand met uw databasewachtwoord, bevindt zich boven de document root waar Apache het nooit zal serveren.

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

configtest zou Syntax OK moeten weergeven. AllowEncodedSlashes On lijkt optioneel, maar dat is het niet: de Google Reader API verstuurt feed-identifiers die %2F bevatten. Zonder deze instructie weigert Apache deze, waardoor mobiele apps niet synchroniseren terwijl de webinterface perfect blijft werken.

Voeg HTTPS toe voordat u inlogt

U staat op het punt een wachtwoord in te voeren op deze site, dus installeer eerst een certificaat. Wijs een A-record naar de server, volg daarna de Certbot-installatie 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 redirect toe. Controleer dit met curl -I https://rss.example.com/, wat een 200 of een redirect naar de inlogpagina zou moeten retourneren.

De installer uitvoeren vanaf de command line

FreshRSS beschikt over een installer via de browser, maar de command line-versie is herhaalbaar en legt precies vast welke keuzes u heeft 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 commando's uit als www-data. Wanneer u deze als root uitvoert, worden configuratiebestanden aangemaakt waarvan root de eigenaar is; de webinterface kan hierdoor later geen instellingen opslaan. --environment production is eveneens van belang, omdat de ontwikkelingsinstelling PHP-meldingen direct op de pagina toont.

Laad https://rss.example.com/ en log in als admin.

Waarom feeds niet automatisch verversen

Niets haalt uw feeds op totdat u dit instelt. FreshRSS ververst alleen wanneer een browser op de pagina is geopend. Dit betekent dat een instantie die u twee keer per dag bezoekt, artikelen toont die twaalf uur oud zijn. De oplossing is het script dat het project hiervoor meelevert, app/actualize_script.php, uitgevoerd via cron.

sudo crontab -u www-data -e

Voeg één regel toe:

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

Twintig minuten is het verstandige minimum. Het script weigert namelijk om een individuele feed vaker dan eens per twintig minuten te verversen; een strakker schema verbruikt dus alleen onnodig CPU-capaciteit. Voer het script eerst eenmaal handmatig uit:

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

Een gezonde uitvoer toont elke opgehaalde feed en eindigt zonder PHP-foutmelding. Als er helemaal niets wordt geprint, is de cron-gebruiker onjuist. Een rechtenfout op data/ betekent dat de stap chmod -R g+w is overgeslagen.

Uw eerste feeds toevoegen

Gebruik de plus-knop linksboven in de interface, plak een websiteadres en FreshRSS zoekt automatisch de feed-link voor u op. De meeste sites publiceren er nog steeds een, zelfs als ze er niet expliciet naar verwijzen; meestal op /feed, /rss of /atom.xml. Categorieën fungeren als mappen en het verplaatsen van een feed tussen deze mappen is een kwestie van slepen.

Als u overstapt vanaf een andere reader, exporteer daar dan een OPML-bestand en importeer dit via de pagina voor abonnementsbeheer. OPML (outline processor markup language) is het standaardformaat voor feedlijsten en elke volwaardige reader ondersteunt dit. Een grote import is traag bij de eerste verversing omdat elke feed eenmalig wordt opgehaald; geef de eerste cron-taak daarom de tijd voordat u de snelheid beoordeelt.

Lees het op uw telefoon

FreshRSS ondersteunt de Google Reader API, waarvoor vrijwel elke RSS-app ondersteuning biedt. Twee voorwaarden moeten zijn vervuld. Onder de authenticatie-instellingen moet "Allow API access" zijn ingeschakeld; de --api-enabled-vlag hierboven heeft dit reeds geconfigureerd. Onder uw profiel moet het veld voor het API-wachtwoord een waarde bevatten. Dit wachtwoord staat bewust los van uw inlogwachtwoord, omdat een telefoon een apparaat is dat u makkelijker kunt verliezen.

Bezoek https://rss.example.com/api/ en kies "Check full server configuration". Een werkende configuratie geeft PASS terug. Een foutmelding hier wijst bijna altijd op de ontbrekende AllowEncodedSlashes On-regel. Voer in de app het serveradres in als https://rss.example.com/api/greader.php, de gebruikersnaam als uw FreshRSS-gebruiker en het API-wachtwoord als het wachtwoord.

Het Docker-alternatief

Als u liever geen PHP en Apache handmatig onderhoudt, publiceert het project een officiële freshrss/freshrss-image. Met één compose-bestand beschikt u direct over de applicatie en de bijbehorende database. De afweging is de gebruikelijke: minder bewegende delen op de host, maar een extra laag om te debuggen bij problemen. Bovendien blijft een reverse proxy noodzakelijk voor TLS (transport layer security). Als dit beter bij uw werkwijze past, behandelt de basis van Docker Compose voor een VPS het bestandsformaat en wordt de cron-regel docker exec --user www-data freshrss php ./app/actualize_script.php.

Back-ups en upgrades

Twee onderdelen bepalen uw status: de database en /srv/freshrss/data/. Maak een dump van de eerste met sudo mysqldump freshrss > freshrss.sql, kopieer de tweede en bewaar beide op een andere locatie dan deze server. Het is ook raadzaam om af en toe een OPML-export van uw abonnementslijst te maken, aangezien dat bestand uw leesomgeving in elke willekeurige RSS-software kan herstellen.

Upgraden houdt in dat u een nieuwere release uitpakt over dezelfde map en de commando's voor eigenaarschap opnieuw uitvoert. FreshRSS voert bij het laden van de volgende pagina automatisch de benodigde database-migraties uit. Maak eerst een back-up, want een mislukte migratie op een database die u niet kunt herstellen, leidt tot gegevensverlies. Een RSS-lezer is een dienst met een laag risico en een uitstekende eerste kandidaat als u werkt aan een lijst met applicaties die de moeite waard zijn om zelf te hosten.

FAQ

Waarom worden mijn feeds alleen bijgewerkt wanneer ik FreshRSS open?

Omdat er geen scheduler bestaat totdat u er een aanmaakt. FreshRSS ververst feeds terwijl een browsersessie openstaat en doet niets wanneer het tabblad is gesloten. Voeg de cron-regel toe die app/actualize_script.php aanroept als de www-data-gebruiker, voer het script daarna eenmaal handmatig uit en lees de uitvoer. Stilte betekent meestal dat cron het script uitvoert als de verkeerde gebruiker, waardoor PHP niet naar data/ kan schrijven.

Mijn mobiele app kan geen verbinding maken, maar de website werkt wel. Hoe komt dit?

De Google Reader API plaatst gecodeerde slashes (%2F) in verzoekpaden, en Apache wijst deze standaard af. Voeg AllowEncodedSlashes On toe binnen de virtual host en herlaad Apache. Bevestig de oplossing door https://rss.example.com/api/ te openen en "Check full server configuration" uit te voeren; dit zou PASS moeten rapporteren. Controleer ook of het API-wachtwoord is ingesteld in uw profiel, aangezien dit losstaat van uw inlogwachtwoord.

Moet ik SQLite of MariaDB gebruiken?

Gebruik SQLite voor een enkele gebruiker, omdat er niets geïnstalleerd hoeft te worden en er geen wachtwoord beheerd hoeft te worden. Gebruik MariaDB zodra meer dan één persoon de instantie leest, of zodra u enkele honderden feeds overschrijdt, omdat de ververstaak en de webinterface tegelijkertijd schrijven en een enkel bestands-lock dan de beperkende factor wordt. Later overstappen tussen beide is mogelijk via de export- en importcommando's, dus dit is geen definitieve beslissing.

De installer faalt bij het schrijven van de configuratie. Wat is er mis?

PHP draait als www-data onder Apache, en die gebruiker kan niet schrijven in een map 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 daarna de installer opnieuw. Als u de command-line installer al als root heeft uitgevoerd, verwijder dan de bestanden die zijn aangemaakt onder data/ voordat u het opnieuw probeert, omdat het eigenaarschap van deze bestanden het werkelijke probleem is.

Hoeveel servercapaciteit heeft een zelfgehoste RSS-lezer nodig?

Zeer weinig. Enkele honderden feeds op een klein abonnement is comfortabel, aangezien de belasting bestaat uit korte uitbarstingen van HTTP-verzoeken om de twintig minuten en de database klein blijft zodra oude artikelen worden verwijderd. De schijfruimte groeit met de retentie, dus stel een beleid voor het opschonen van artikelen in bij de archiveringsinstellingen in plaats van alles voor altijd te bewaren.