Come installare FreshRSS su un VPS Ubuntu
Installa FreshRSS 1.29.1 su Ubuntu 24.04 con Apache, PHP 8.3 e MariaDB: release tarball, virtual host, cron per i feed e API per l'app mobile.
Cosa stai configurando
Un lettore RSS self-hosted è un lettore di feed eseguito su un server di tua proprietà. Nessuno può quindi arrestarlo o modificare i contenuti che visualizza. Questa guida installa FreshRSS su un VPS Ubuntu 24.04: Apache come frontend, PHP come backend, MariaDB per l'archiviazione e un job cron che recupera i nuovi articoli. RSS (really simple syndication) è il formato di file che un sito pubblica affinché i software possano leggere i relativi articoli. FreshRSS è l'applicazione PHP che raccoglie questi file, conserva gli articoli e mette a disposizione un'interfaccia web e un'API (application programming interface) utilizzata dalle app per smartphone.
L'installazione è semplice: estrarre una release, creare un database, scrivere un virtual host ed eseguire un installer dalla riga di comando. La maggior parte delle operazioni successive riguarda gli aspetti che causano più problemi: il job di aggiornamento, le slash codificate per l'API mobile e la proprietà dei file.
FreshRSS 1.29.1 è la release corrente a luglio 2026 e richiede PHP 8.1 o versioni successive. Ubuntu 24.04 include PHP 8.3, quindi sono sufficienti i pacchetti della distribuzione e non serve un repository PHP di terze parti.
Parti da uno stack LAMP funzionante
FreshRSS è una normale applicazione PHP, quindi richiede la stessa base delle altre applicazioni. Se non hai ancora predisposto questa base, segui prima la procedura di configurazione dello stack LAMP per Ubuntu 24.04, quindi torna qui. In sintesi:
sudo apt update
sudo apt install -y apache2 mariadb-server php libapache2-mod-php
sudo systemctl enable --now apache2 mariadbsystemctl status apache2 dovrebbe restituire active (running). Se Apache non si avvia, la causa più comune è un altro processo che sta già occupando la porta 80; sudo ss -ltnp | grep :80 ne indica il processo.
Le estensioni PHP richieste da FreshRSS
FreshRSS considera obbligatorie libxml, cURL, JSON, PDO_MySQL, PCRE e ctype. Richiede inoltre mbstring, iconv, Zlib e ZipArchive, oltre a GMP sui sistemi a 32 bit. Su Ubuntu queste estensioni sono disponibili come pacchetti della distribuzione:
sudo apt install -y php-curl php-mbstring php-xml php-zip php-mysql php-intl php-gmp
sudo systemctl restart apache2Verifica quali estensioni PHP sono effettivamente caricate con php -m. Un'estensione mancante non impedisce l'avvio dell'installer. L'installazione si interrompe invece nella schermata dei requisiti, con una riga rossa che indica l'estensione mancante. È un punto poco intuitivo in cui scoprire il problema, quindi esegui subito questa verifica. Il riavvio di Apache è necessario perché libapache2-mod-php mantiene PHP all'interno del processo Apache. Di conseguenza, il web server non rileva una nuova estensione finché non viene riavviato.
Scaricare la release
Installare FreshRSS al di fuori della document root predefinita e configurare Apache per raggiungerla. Mantenere separata la directory dell'applicazione dalla document root significa che tramite HTTP sarà raggiungibile soltanto la directory pubblica.
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/freshrssImpostare ora i permessi, come richiesto dalla documentazione di FreshRSS: l'utente del server web deve essere il proprietario dell'albero delle directory, il gruppo deve poter leggere ogni file e deve poter scrivere in ./data/.
sudo chown -R www-data:www-data /srv/freshrss
sudo chmod -R g+r /srv/freshrss
sudo chmod -R g+w /srv/freshrss/dataSe si omette questo passaggio, l'installer non riesce a scrivere la configurazione, perché PHP viene eseguito come www-data e www-data non può scrivere in una directory di proprietà di root.
Crea il database
FreshRSS supporta SQLite, MariaDB, MySQL e PostgreSQL. SQLite non richiede configurazione ed è adatto a una singola persona con alcune centinaia di feed. MariaDB è la scelta migliore quando più persone condividono l'istanza, perché le scritture concorrenti del processo di aggiornamento e dell'interfaccia web non competono più per un singolo blocco di file.
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;"Usa utf8mb4 e non utf8. I feed possono contenere emoji e alfabeti non latini, mentre la vecchia codifica utf8 a tre byte tronca il titolo di un articolo al primo carattere a quattro byte.
L’host virtuale Apache
La directory pubblica è p/, non la directory principale dell’albero. Tutto il resto, incluso il file di configurazione che contiene la password del database, si trova sopra la document root, dove Apache non lo pubblicherà mai.
<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>Salva il file come /etc/apache2/sites-available/freshrss.conf e abilitalo:
sudo a2enmod rewrite
sudo a2ensite freshrss
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2configtest dovrebbe visualizzare Syntax OK. AllowEncodedSlashes On sembra facoltativo, ma non lo è: l’API Google Reader invia identificativi dei feed contenenti %2F e, senza questa direttiva, Apache li rifiuta. Di conseguenza, le applicazioni mobili non riescono a sincronizzarsi, mentre l’interfaccia web continua a funzionare correttamente.
Aggiungi HTTPS prima di accedere
Stai per inserire una password in questo sito, quindi procurati prima un certificato. Configura un record A che punti al server, quindi segui la procedura di configurazione di Certbot per Apache su Ubuntu ed esegui sudo certbot --apache -d rss.example.com. Certbot riscrive il virtual host per la porta 443 e aggiunge il redirect. Verifica con curl -I https://rss.example.com/: il comando dovrebbe restituire un 200 oppure un redirect alla pagina di accesso.
Esegui l'installer dalla riga di comando
FreshRSS include un installer nel browser, ma la versione dalla riga di comando è ripetibile e conserva una registrazione esatta delle opzioni selezionate.
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'Esegui entrambi i comandi come www-data. Se li esegui come root, i file di configurazione vengono creati con root come proprietario e l'interfaccia web non riesce più a salvare le impostazioni. Anche --environment production è importante, perché l'impostazione di sviluppo stampa le notifiche PHP nella pagina.
Carica https://rss.example.com/ e accedi con admin.
Perché i feed non si aggiornano da soli
Nessun processo interroga i feed finché non lo configuri. FreshRSS esegue l'aggiornamento mentre nel browser è aperta la relativa pagina. Un'istanza visitata due volte al giorno mostra quindi articoli vecchi di dodici ore. La soluzione è lo script fornito dal progetto per questo scopo, app/actualize_script.php, eseguito tramite cron.
sudo crontab -u www-data -eAggiungi una riga:
*/20 * * * * php /srv/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1Venti minuti sono l'intervallo minimo consigliato. Lo script non aggiorna infatti lo stesso feed più spesso di una volta ogni venti minuti. Un intervallo più breve consuma soltanto CPU. Eseguilo prima manualmente:
sudo -u www-data php /srv/freshrss/app/actualize_script.phpUn'uscita corretta elenca ogni feed recuperato e termina senza errori PHP. Se non stampa nulla, l'utente di cron è errato. Un errore di autorizzazione su data/ indica che il passaggio chmod -R g+w è stato saltato.
Aggiungi i primi feed
Usa il pulsante con il segno più in alto a sinistra dell'interfaccia, incolla l'indirizzo di un sito e FreshRSS individuerà automaticamente il link del feed. La maggior parte dei siti ne pubblica ancora uno anche quando non lo indica esplicitamente, di solito in /feed, /rss o /atom.xml. Le categorie sono cartelle e per spostare un feed da una categoria all'altra basta trascinarlo.
Se provieni da un altro lettore, esporta da quel lettore un file OPML e importalo nella pagina di gestione delle sottoscrizioni. OPML (outline processor markup language) è il formato standard per gli elenchi di feed e tutti i lettori che vale la pena usare supportano l'esportazione in questo formato. Un'importazione di grandi dimensioni è lenta al primo aggiornamento perché ogni feed viene recuperato una volta; attendi quindi che il primo avvio di cron termini prima di valutare la velocità.
Lettura sul telefono
FreshRSS supporta l'API di Google Reader, compatibile con quasi tutte le applicazioni RSS. Devono essere vere due condizioni. Nelle impostazioni di autenticazione, l'opzione "Allow API access" deve essere attiva; il flag --api-enabled indicato sopra l'ha già impostata. Nel profilo, il campo della password API deve contenere un valore. È separato intenzionalmente dalla password di accesso, perché un telefono è più facile da perdere.
Visita https://rss.example.com/api/ e scegli "Check full server configuration". Una configurazione funzionante restituisce PASS. Se il controllo fallisce, nella quasi totalità dei casi manca la riga AllowEncodedSlashes On. Nell'app, inserisci l'indirizzo del server come https://rss.example.com/api/greader.php, il nome utente del tuo account FreshRSS e la password API nel campo della password.
L’alternativa Docker
Se preferisci non gestire manualmente PHP e Apache, il progetto pubblica un’immagine ufficiale freshrss/freshrss e un unico file Compose configura insieme l’applicazione e il relativo database. Il compromesso è quello consueto: meno componenti da gestire sull’host, ma un ulteriore livello da analizzare quando qualcosa non funziona. Per TLS (transport layer security) serve comunque un reverse proxy. Se questa soluzione è più adatta alle tue esigenze, le nozioni di base su Docker Compose per un VPS descrivono il formato del file; la riga di cron diventa docker exec --user www-data freshrss php ./app/actualize_script.php.
Backup e aggiornamenti
Lo stato è conservato in due elementi: il database e /srv/freshrss/data/. Esegui il dump del primo con sudo mysqldump freshrss > freshrss.sql, copia il secondo e conserva entrambi in una posizione diversa da questo server. Anche l’elenco delle sottoscrizioni merita un’esportazione OPML periodica, perché questo file consente di ricreare la configurazione di lettura con qualsiasi software RSS.
Per aggiornare FreshRSS, estrai una release più recente nella stessa directory ed esegui nuovamente i comandi per impostare la proprietà. FreshRSS applica le proprie migrazioni del database al caricamento della pagina successivo. Esegui prima il backup, perché una migrazione non riuscita su un database che non puoi ripristinare produce una situazione irrecuperabile. Un reader è un servizio a basso rischio da eseguire e un buon primo candidato se stai valutando un elenco di ciò che vale la pena self-hostare.
FAQ
Perché i miei feed si aggiornano solo quando apro FreshRSS?
Perché non esiste alcuna pianificazione finché non ne crei una. FreshRSS aggiorna i feed mentre è aperta una sessione del browser e non esegue alcuna attività quando la scheda viene chiusa. Aggiungi la riga cron che richiama app/actualize_script.php come utente www-data, quindi esegui manualmente lo script una volta e leggine l'output. In genere, l'assenza di output indica che cron lo esegue con l'utente sbagliato e che PHP non può scrivere in data/.
La mia app mobile non riesce a connettersi, ma il sito web funziona. Perché?
La Google Reader API inserisce slash codificati (%2F) nei percorsi delle richieste e Apache li rifiuta per impostazione predefinita. Aggiungi AllowEncodedSlashes On all'interno del virtual host e ricarica Apache. Verifica la correzione aprendo https://rss.example.com/api/ ed eseguendo "Check full server configuration", che dovrebbe indicare PASS. Controlla anche che la password API sia impostata nel tuo profilo, perché è distinta dalla password di accesso.
Devo usare SQLite o MariaDB?
SQLite per un singolo utente, perché non richiede installazione né la gestione di una password. MariaDB quando nell'istanza legge più di una persona o quando superi qualche centinaio di feed, perché il processo di aggiornamento e l'interfaccia web scrivono contemporaneamente e il lock su un singolo file diventa il limite. In seguito è possibile passare da un database all'altro tramite i comandi di esportazione e importazione, quindi non è una decisione permanente.
L'installer non riesce a scrivere la configurazione. Qual è il problema?
PHP viene eseguito come www-data da Apache e questo utente non può scrivere in una directory di proprietà di root. Esegui nuovamente sudo chown -R www-data:www-data /srv/freshrss e sudo chmod -R g+w /srv/freshrss/data, quindi riavvia l'installer. Se hai già eseguito l'installer dalla riga di comando come root, elimina i file creati in data/ prima di riprovare, perché il problema effettivo è il loro proprietario.
Di quante risorse server ha bisogno un lettore RSS self-hosted?
Di pochissime. Qualche centinaio di feed su un piano di piccole dimensioni viene gestito senza problemi, perché il carico consiste in brevi raffiche di richieste HTTP ogni venti minuti e il database rimane contenuto quando gli articoli meno recenti vengono eliminati. Lo spazio su disco cresce in base al periodo di conservazione, quindi imposta una politica di eliminazione degli articoli nelle impostazioni di archiviazione invece di conservarli per sempre.