Installare Nextcloud sul proprio server
Dal server vuoto alla panoramica senza avvisi: web server, moduli PHP, database, permessi sulla directory dei dati, trusted_domains, limiti di upload e job in background via cron.
Scompattare Nextcloud richiede pochi secondi. La parte che costa tempo viene dopo: su un'installazione appena creata la pagina di panoramica sotto Impostazioni di amministrazione mostra quasi sempre un elenco di avvisi gialli e rossi, gli upload si interrompono a 2 MB e la chiamata tramite indirizzo IP finisce con "You are accessing the site from an untrusted domain.". Questo articolo percorre l'intero tragitto e si ferma proprio nei punti in cui la maggior parte delle guide smette.
Da decidere prima: versione di PHP, database, posizione dei dati
Nextcloud dipende dalla versione di PHP molto più della maggior parte degli altri software server. Le serie attuali 33 e 34 richiedono almeno PHP 8.2, la serie 32 gira ancora a partire da PHP 8.1. È quindi la distribuzione a decidere se ti bastano gli strumenti di bordo:
| Sistema | PHP della distribuzione | Database della distribuzione | Valutazione |
|---|---|---|---|
| Debian 13 (trixie) | 8.4 | MariaDB 11.8 | va bene senza repository esterni |
| Debian 12 (bookworm) | 8.2 | MariaDB 10.11 | va bene, ma è al limite inferiore |
| Ubuntu 24.04 LTS | 8.3 | MariaDB 10.11, MySQL 8.0 | va bene senza repository esterni |
| Ubuntu 22.04 LTS | 8.1 | MariaDB 10.6, MySQL 8.0 | troppo vecchio per Nextcloud 33 e 34 |
| Debian 11 (bullseye) | 7.4 | MariaDB 10.5 | da escludere |
Debian 11 è il caso più duro e tende comunque a farsi notare tardi, perché l'installazione dei pacchetti va a buon fine senza errori. Lì il metapacchetto php tira dietro PHP 7.4, e la versione attuale di Nextcloud si interrompe alla prima chiamata nel browser con HTTP 500 e il messaggio "This version of Nextcloud requires at least PHP 8.2". Debian 11 è comunque uscito dal supporto regolare e come base per una nuova installazione è la scelta sbagliata. Se proprio non puoi farne a meno, aggiungi prima il repository Sury e installa esplicitamente i pacchetti con numero di versione, quindi php8.2-fpm, php8.2-cli, php8.2-mysql e così via, invece dei metapacchetti senza versione.
Anche su Ubuntu 22.04 finisci inevitabilmente contro un muro non appena installi la versione attuale di Nextcloud. O resti consapevolmente sulla serie 32, oppure prendi PHP dal noto PPA:
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:ondrej/php
sudo apt-get update
sudo apt-get install -y php8.3-fpm php8.3-cli php8.3-mysql
Altri due punti che si fissano all'inizio e che dopo si cambiano solo a fatica: Debian non fornisce in nessun caso un pacchetto mysql-server, lì la scelta obbligata è MariaDB. E la directory dei dati non va sotto /var/www/nextcloud/data, ma fuori dalla radice del web server, per esempio in /var/nextcloud-data. Il percorso predefinito è pericoloso per un motivo preciso: con una configurazione del web server rotta, tutti i file degli utenti finirebbero serviti in chiaro. In quel caso Nextcloud avverte con "Your data directory and files are probably accessible from the internet", ma solo dopo che l'errore esiste già.
Configurare web server, PHP e database
Qui usiamo nginx con PHP-FPM. Se preferisci Apache con mod_php, il percorso è descritto in Apache, PHP e MySQL su Debian, mentre gli argomenti su PHP più avanti restano validi senza modifiche. Un'installazione di base di nginx la trovi in installare nginx.
sudo apt-get update
sudo apt-get install -y nginx mariadb-server
sudo apt-get install -y php-fpm php-cli php-mysql php-gd php-curl php-mbstring php-intl php-gmp php-bcmath php-xml php-zip php-imagick php-apcu
Questo elenco è volutamente più lungo del minimo indispensabile. Nextcloud usa bcmath e gmp per l'accesso senza password, intl per l'ordinamento corretto di lettere accentate e caratteri speciali, imagick per le anteprime, apcu per la cache locale. Se manca uno dei moduli obbligatori non superi nemmeno la procedura guidata di installazione: la pagina elenca allora per nome i moduli mancanti.
Verifica poi che cosa viene effettivamente caricato:
php -v
php -m
Il secondo inciampo frequente: esistono due configurazioni PHP separate, una per la riga di comando e una per FPM. php --ini ti mostra quella della riga di comando, quella del web server si trova sotto /etc/php/<version>/fpm/php.ini. Le modifiche al file sbagliato non hanno alcun effetto, ed è proprio questo a rubare in genere più tempo di tutto il resto.
Ora il database. Metti prima in sicurezza MariaDB, vedi mettere in sicurezza MariaDB e MySQL, poi:
sudo mariadb -e "CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
sudo mariadb -e "CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'QuiUnaPasswordLunga';"
sudo mariadb -e "GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';"
sudo mariadb -e "FLUSH PRIVILEGES;"
Il utf8mb4 nel primo comando non è un dettaglio. Se crei il database con utf8, più avanti Nextcloud segnala "MySQL is used as database but does not support 4-byte characters", e la conversione a sistema in esercizio è molto più fastidiosa del CREATE DATABASE giusto fin dall'inizio. Se l'accesso dell'utente del database fallisce, ti aiuta risolvere Access denied for user.
Scompattare e impostare i permessi
sudo apt-get install -y wget unzip
wget https://download.nextcloud.com/server/releases/latest.zip
sudo unzip -q latest.zip -d /var/www
sudo mkdir -p /var/nextcloud-data
sudo chown -R www-data:www-data /var/www/nextcloud
sudo chown -R www-data:www-data /var/nextcloud-data
sudo chmod 750 /var/nextcloud-data
I permessi sono il punto in cui si lavora più spesso in modo approssimativo. Tre quadri d'errore e la loro causa:
- "Cannot write into config directory":
/var/www/nextcloud/confignon appartiene all'utente del web server. Su Debian e Ubuntu èwww-data, su AlmaLinux e Rocky inveceapacheoppurenginx. Unchown www-datacopiato alla cieca non produce nulla sulla famiglia Red Hat. - "Can't create or write into the data directory": il percorso non esiste, non è un percorso assoluto, oppure una directory superiore non è attraversabile da
www-data. - "Your data directory is readable by other users": permessi troppo larghi. Basta
chmod 750sulla directory dei dati.
Resisti alla tentazione di risolvere il problema a martellate con chmod -R 777. Nextcloud risponde con esattamente l'avviso che volevi togliere di mezzo e, per giunta, hai reso ogni file leggibile a qualunque utente locale.
La configurazione di nginx
Nextcloud ha bisogno di più di un normale blocco PHP, tra le altre cose di riscritture per il rilevamento dei servizi sotto /.well-known/ e di blocchi per le directory interne. Quella che segue è la versione ridotta del modello ufficiale e funziona così com'è:
upstream php-handler {
server unix:/run/php/php8.3-fpm.sock;
}
server {
listen 80;
server_name cloud.example.com;
root /var/www/nextcloud;
client_max_body_size 10G;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
index index.php index.html /index.php$request_uri;
location ^~ /.well-known {
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
return 301 /index.php$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
location ~ \.php(?:$|/) {
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_request_buffering off;
fastcgi_max_temp_file_size 0;
}
location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|map|woff2)$ {
try_files $uri /index.php$request_uri;
expires 6M;
access_log off;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}
Il percorso del socket FPM va adattato alla tua versione di PHP. Su Debian 13 si chiama php8.4-fpm.sock, su Debian 12 php8.2-fpm.sock, su Ubuntu 24.04 php8.3-fpm.sock e su Ubuntu 22.04 php8.1-fpm.sock. Se il nome non corrisponde ottieni un 502 Bad Gateway. Il nome reale lo mostra:
systemctl enable --now php8.4-fpm
ls /run/php/
La prima riga fa parte del gioco, perché il file socket nasce solo all'avvio del servizio. Prima /run/php/ è vuota oppure non esiste affatto, e ls risponde con No such file or directory. Su un server normale è il pacchetto stesso ad avviare il servizio durante l'installazione, ma dopo una reinstallazione o dentro un container questo non è garantito. Adatta il numero di versione nel nome del servizio alla tua installazione. Poi nginx -t e ricarica.
Installazione, HTTPS e trusted_domains
Puoi completare l'installazione cliccando nel browser oppure sbrigarla subito dalla riga di comando. La seconda variante è riproducibile e si può mettere in uno script:
cd /var/www/nextcloud
sudo -u www-data php occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "nextcloud" --database-pass "QuiUnaPasswordLunga" --admin-user "admin" --admin-pass "UnAltraPasswordLunga" --data-dir "/var/nextcloud-data"
Qui ci sono due trappole. Primo: il comando deve girare dalla directory di Nextcloud, altrimenti PHP si interrompe con un fatal error. Secondo: occ non deve mai girare come root, altrimenti arriva "Console has to be executed with the user that owns the file config/config.php" e, nel caso peggiore, i file appena creati appartengono poi all'utente sbagliato.
Ora HTTPS. Senza certificato le app mobili si rifiutano di collegarsi e Nextcloud avvisa nella panoramica:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.example.com
Per più sottodomini conviene un certificato wildcard. Aggiungi poi nel blocco server TLS l'header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;, altrimenti resta l'avviso "The Strict-Transport-Security HTTP header is not configured to at least 15552000 seconds".
Il classico per finire: apri il sito con un nome diverso da quello usato durante l'installazione e vedi soltanto "You are accessing the site from an untrusted domain." Nextcloud accetta esclusivamente i nomi host presenti in trusted_domains. Per aggiungerne uno senza modificare il file a mano:
sudo -u www-data php occ config:system:set trusted_domains 1 --value=cloud.example.com
sudo -u www-data php occ config:system:get trusted_domains
L'indice parte da 0, e lo 0 di solito è già occupato. Se assegni due volte lo stesso indice sovrascrivi la voce esistente e in certi casi ti chiudi fuori da solo. Se succede: config/config.php è un normalissimo file PHP e la voce si corregge lì con un editor. Imposta inoltre overwrite.cli.url sull'indirizzo HTTPS definitivo, altrimenti i job in background generano link con il nome host sbagliato.
Dimensione degli upload e limite di memoria
Le impostazioni predefinite di PHP sono troppo strette per Nextcloud. upload_max_filesize di norma è su 2M, memory_limit su 128M. Nextcloud consiglia almeno 512M di memoria e altrimenti avvisa con "The PHP memory limit is below the recommended value of 512MB".
Qui i punti in gioco sono tre, e toccarne uno solo non basta:
- La configurazione di FPM sotto
/etc/php/<version>/fpm/php.ini:memory_limit = 512M,upload_max_filesize = 10G,post_max_size = 10G,max_execution_time = 3600. Poi riavvia FPM, un semplice ricaricamento di nginx non basta. - Il file
.user.ininella directory di Nextcloud: Nextcloud porta con sé valori propri e, poiché.user.inivale a livello di directory, vince sullaphp.iniglobale. È proprio qui che la ricerca dell'errore si arena di continuo. Adatta i valori anche lì. PHP tiene questo file in cache, per impostazione predefinita cinque minuti, quindi la tua modifica ha effetto in ritardo. - La direttiva nginx
client_max_body_size: se manca o è troppo piccola, l'upload si interrompe con "413 Request Entity Too Large" prima ancora che PHP venga interpellato.
Per verificare che cosa arriva davvero in fondo aiuta la pagina Impostazioni di amministrazione, dove è indicato il limite superiore realmente attivo. Dalla riga di comando:
grep -E '^(memory_limit|upload_max_filesize|post_max_size)' /etc/php/8.4/fpm/php.ini
Interroga esplicitamente il file di FPM e non la riga di comando. Un php -r "echo ini_get('memory_limit');" legge la SAPI CLI, e su tutte le distribuzioni verificate quella riporta -1, cioè illimitato. Chi si fida di quel valore lo considera sufficiente e più avanti finisce lo stesso in errori di memoria, perché nel file di FPM continua a esserci memory_limit = 128M. Quello che arriva davvero nel browser lo mostra php-fpm8.4 -i oppure un info.php depositato per poco tempo con phpinfo(), che poi cancelli subito.
Se durante il caricamento di file grandi il processo viene terminato dal kernel, semplicemente manca RAM. In quel caso configurare lo swap serve da ripiego, ma la soluzione migliore è più RAM.
Passare i job in background a cron
Dopo l'installazione Nextcloud gira in modalità AJAX: i job in background vengono eseguiti solo se in quel momento qualcuno ha l'interfaccia aperta. È questo il motivo per cui su istanze poco usate ricerca full text, pulizie e notifiche sembrano non avvenire affatto. Passa a un cron vero, Nextcloud si aspetta un'esecuzione ogni cinque minuti. Le basi sono in configurare un cronjob su Linux.
sudo crontab -u www-data -e
Lì inserisci:
*/5 * * * * php -f /var/www/nextcloud/cron.php
Poi comunica a Nextcloud il cambio di modalità:
cd /var/www/nextcloud
sudo -u www-data php occ background:cron
Chi preferisce lavorare senza demone cron usa un servizio systemd con timer. La unit nextcloudcron.service richiama /usr/bin/php -f /var/www/nextcloud/cron.php come utente www-data, il timer corrispondente imposta OnBootSec=5min e OnUnitActiveSec=5min.
Se l'avviso "Last background job execution ran X hours ago. Something seems wrong" resta comunque, controlla in quest'ordine: il job gira con l'utente giusto? Il percorso esiste davvero? E un punto molto importante: cron.php è eseguibile con la configurazione PHP della riga di comando, oppure lì manca un modulo installato solo per FPM? Il test più onesto è la chiamata a mano, così vedi ogni messaggio d'errore in chiaro:
sudo -u www-data php -f /var/www/nextcloud/cron.php
Smaltire gli avvisi della panoramica
L'elenco sotto Impostazioni di amministrazione e Panoramica non è un ornamento, ogni riga ha un motivo concreto. I casi più frequenti e la loro soluzione:
- "No memory cache has been configured": APCu è installato, ma non registrato.
occ config:system:set memcache.local --value='\OC\Memcache\APCu'. Perché ne traggano vantaggio ancheocce le esecuzioni di cron, imposta inoltreapc.enable_cli=1in/etc/php/<version>/mods-available/apcu.ini. - "Transactional file locking is disabled": installa Redis (
apt-get install -y redis-server php-redis) e impostamemcache.lockingsu\OC\Memcache\Redis. Su istanze a utente singolo se ne può fare a meno, ma non appena più utenti sincronizzano contemporaneamente diventa necessario. - "Your web server is not properly set up to resolve /.well-known/caldav": mancano le riscritture nel blocco
location ^~ /.well-known. Lo verifichi direttamente concurl -I https://cloud.example.com/.well-known/caldav, ci si aspetta un 301 verso/remote.php/dav/. - "Your installation has no default phone region set":
occ config:system:set default_phone_region --value="AT", per l'ItaliaIT. Il valore è un codice paese secondo ISO 3166-1. - "Server has no maintenance window start time configured":
occ config:system:set maintenance_window_start --type=integer --value=1. Il valore è l'ora di inizio in UTC, così i job giornalieri pesanti girano di notte invece che in pieno esercizio. - "The database is missing some indexes":
occ db:add-missing-indices, insieme aocc db:add-missing-columnseocc db:add-missing-primary-keys. Su istanze grandi questi comandi sono lenti, ma non pericolosi. - "PHP does not seem to be setup properly to query system environment variables": nel file di pool di FPM
/etc/php/<version>/fpm/pool.d/www.conftogli il commento alla rigaenv[PATH] = /usr/local/bin:/usr/bin:/bine riavvia FPM. - "Module php-imagick in this instance has no SVG support": non è un errore di Nextcloud, ma una libreria delegate mancante in ImageMagick. Se non ti servono le anteprime SVG, puoi lasciare l'avviso dov'è.
Come capire che funziona davvero
Quattro verifiche che, prese insieme, dicono qualcosa di concreto:
cd /var/www/nextcloud
sudo -u www-data php occ status
sudo -u www-data php occ check
sudo -u www-data php occ config:app:get core lastcron
occ status deve riportare installed: true e la versione attesa, occ check non deve produrre alcun output. Il terzo comando restituisce un timestamp Unix. Convertilo: non deve essere più vecchio di cinque minuti, solo allora il tuo cron sta davvero lavorando.
Dall'esterno:
curl -s https://cloud.example.com/status.php
La risposta è un oggetto JSON con "installed":true, "maintenance":false e il numero di versione. Se qui torna dell'HTML, una delle tue regole location agisce in modo troppo ampio. Se arriva un reindirizzamento alla pagina di accesso va tutto bene, hai solo preso l'URL sbagliato.
Per ultimo il test sul campo, che nessuna pagina di stato può sostituire: carica un file di diversi gigabyte tramite l'interfaccia web e sincronizzalo poi con il client desktop. Solo così si vede se client_max_body_size, post_max_size, i timeout e lo spazio su disco libero vanno d'accordo. Se all'improvviso si blocca tutto, vale la pena dare un'occhiata ai dischi pieni, perché Nextcloud crea anteprime e versioni che crescono in modo percepibile.
Quando qualcosa va storto
Nextcloud scrive il log in /var/nextcloud-data/nextcloud.log, quindi nella tua directory dei dati e non in /var/log. È questo il primo file da guardare, non il log di nginx. Per un output leggibile:
sudo -u www-data php occ log:watch
Se dopo un aggiornamento interrotto l'istanza resta bloccata in modalità di manutenzione, occ maintenance:mode --off la riporta indietro. Se l'interfaccia non è più raggiungibile del tutto, imposta 'maintenance' => false direttamente in config/config.php.
Prima di mettere mano al database o alla configurazione, fai il backup di entrambi. Un backup della sola directory non basta, senza il database corrispondente Nextcloud non vale nulla:
sudo -u www-data php occ maintenance:mode --on
sudo mariadb-dump --single-transaction nextcloud > /root/nextcloud-db.sql
sudo -u www-data php occ maintenance:mode --off
E un consiglio di fondo: finisci di costruire il server prima di renderlo raggiungibile pubblicamente. Un firewall, un accesso SSH messo in sicurezza e i punti della checklist per i nuovi server root vanno prima del primo accesso, non dopo. Un'istanza Nextcloud con password predefinita viene trovata nel giro di poche ore.
Domande frequenti
Quale versione di PHP serve per Nextcloud?
Perché ricevo "You are accessing the site from an untrusted domain"?
Perché gli upload si interrompono nonostante la php.ini aumentata?
Perché i miei job in background non girano?
Quali permessi servono per la directory dei dati?
Come mi tolgo l'avviso sulla memory cache mancante?
Posso usare Nextcloud anche con PostgreSQL?
2026 KernelHost GmbH. Tutti i diritti riservati. Questa guida è protetta dal diritto d'autore. La ripubblicazione su altri siti web, anche parziale o in forma modificata, non è consentita senza il nostro consenso scritto. Le citazioni con indicazione della fonte e un link sono le benvenute.

