SSD Nodes Learn Hosting plans →
Guide Matt ConnorDi Matt Connor

Nextcloud su VPS con Docker, TLS e backup

Configura Nextcloud su VPS con Docker Compose, Postgres, Redis e proxy TLS. Include backup ripristinabili e upgrade sicuri per proteggere davvero i tuoi dati.

Cosa stai effettivamente configurando

Questa guida esegue Nextcloud su un VPS con Docker Compose, configura TLS tramite Let's Encrypt e imposta un backup che può essere realmente ripristinato. La configurazione usa quattro container e un proxy: l'immagine ufficiale nextcloud in ascolto sull'interfaccia di loopback, Postgres per tutti i metadati dei file, Redis per i file lock, una seconda istanza dell'immagine Nextcloud dedicata esclusivamente al ciclo cron e nginx sull'host, che termina TLS davanti a tutti questi componenti. L'installazione richiede venti minuti, ma non è questo l'aspetto più importante. Due decisioni prese nella prima ora determinano se tra un anno avrai ancora i tuoi file: usare un database reale invece di SQLite e creare un backup che acquisisca la directory dei dati, il database e config.php come un unico insieme coerente.

Questa procedura presuppone Ubuntu 24.04 LTS o Debian 13, Docker Engine con il plugin Compose v2 installato dal repository ufficiale Docker e un record DNS A (oltre a AAAA se disponi di IPv6) già configurato in modo che punti cloud.example.com al VPS. È necessario un server sotto il tuo controllo: non puoi terminare TLS ed eseguire un dump del database sul SaaS di terzi.

Dimensionamento: che cosa consuma effettivamente la memoria

L'uso della memoria di Nextcloud dipende soprattutto da tre componenti, e nessuna di queste è semplicemente "Nextcloud".

Worker PHP. L'immagine -apache gestisce ogni richiesta simultanea tramite un processo worker che contiene un interprete PHP. Ogni worker può arrivare a PHP_MEMORY_LIMIT prima che PHP termini la richiesta. La memoria residente nel caso peggiore è approssimativamente numero di richieste simultanee × limite di memoria; inoltre, un client di sincronizzazione desktop apre diverse connessioni parallele per ogni utente. È la concorrenza, non il numero di utenti, a determinare il limite massimo.

Il database. Postgres crea un processo backend per ogni connessione e mantiene residenti i buffer condivisi. Il suo working set cresce in base al numero di file, non al numero di byte: oc_filecache contiene una riga per ogni file e per ogni utente. Centomila file piccoli richiedono più risorse al database rispetto a cento file grandi.

Generazione delle anteprime. La generazione di una miniatura decodifica l'immagine sorgente in memoria alla risoluzione completa. Le anteprime video invocano ffmpeg tramite la shell. Eseguire occ preview:generate-all ripete questo picco più volte consecutivamente ed è il modo più comune per portare un VPS con poca memoria all'intervento dell'OOM killer.

Redis è relativamente leggero. Qualsiasi componente aggiunto in seguito, come Collabora, la ricerca full-text o uno scanner antivirus, è un servizio residente separato con un proprio consumo di risorse. Deve quindi essere incluso nel dimensionamento prima dell'abilitazione.

Se la RAM è limitata, puoi intervenire su questi parametri: riduci PHP_MEMORY_LIMIT, limita preview_max_x / preview_max_y / preview_max_filesize_image, restringi enabledPreviewProviders ai formati che visualizzi effettivamente e imposta trashbin_retention_obligation e versions_retention_obligation, in modo che la directory dei dati non cresca silenziosamente fino a diverse volte la dimensione dei file. Aggiungi un file di swap. Lo swap è lento e un processo terminato dall'OOM killer durante un aggiornamento causa problemi ancora più gravi.

Perché SQLite si blocca

Nextcloud supporta SQLite e l'immagine ufficiale lo utilizza senza problemi. Non usarlo. SQLite serializza le scritture tramite un lock sull'intero database: è possibile eseguire una sola scrittura alla volta sull'intero file. Nextcloud scrive continuamente dati, lock sui file, righe delle attività, voci della cache e stato dei job. Inoltre, un singolo client desktop che sincronizza un albero di directory genera molte richieste parallele. In questo scenario si verificano SQLSTATE[HY000]: General error: 5 database is locked e risposte HTTP 500. Il problema compare proprio quando l'istanza inizia a essere utilizzata concretamente.

La conversione successiva è possibile con occ db:convert-type, ma consiste in una migrazione lunga e indivisibile su un dataset attivo. Inizia con Postgres o MariaDB.

Il file Compose

Inseriscilo in /srv/nextcloud/compose.yaml e conserva i secret nel file .env affiancato, con modalità 600.

services:
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - db:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: ${DB_PASSWORD}

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_PASSWORD}

  app:
    image: nextcloud:35-apache
    restart: unless-stopped
    depends_on: [db, redis]
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - html:/var/www/html
      - /srv/nextcloud/data:/var/www/html/data
    environment:
      POSTGRES_HOST: db
      POSTGRES_DB: nextcloud
      POSTGRES_USER: nextcloud
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      REDIS_HOST: redis
      REDIS_HOST_PASSWORD: ${REDIS_PASSWORD}
      NEXTCLOUD_ADMIN_USER: admin
      NEXTCLOUD_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
      NEXTCLOUD_TRUSTED_DOMAINS: cloud.example.com
      TRUSTED_PROXIES: 172.16.0.0/12
      OVERWRITEPROTOCOL: https
      OVERWRITECLIURL: https://cloud.example.com
      APACHE_DISABLE_REWRITE_IP: "1"
      PHP_MEMORY_LIMIT: 512M
      PHP_UPLOAD_LIMIT: 10G

  cron:
    image: nextcloud:35-apache
    restart: unless-stopped
    entrypoint: /cron.sh
    depends_on: [db, redis]
    volumes:
      - html:/var/www/html
      - /srv/nextcloud/data:/var/www/html/data

volumes:
  db:
  html:

Blocca il tag principale e verifica quello attuale su Docker Hub prima di copiare 35 senza modifiche. Al 21 ottobre 2026, Nextcloud mantiene le versioni 33, 34 e 35. La versione 31 ha raggiunto la fine del ciclo di vita a febbraio 2026 e la 32 a settembre 2026; un tag copiato da una guida precedente installa quindi una release che non riceve più correzioni. latest eseguirà il passaggio oltre un confine di versione principale in un futuro docker compose pull e Nextcloud non supporta questa procedura.

La directory dei dati è un bind mount, non un volume denominato, intenzionalmente: poter indicare direttamente il percorso a uno strumento di backup è più importante dell'ordine della configurazione. Creala con l'UID www-data dell'immagine e con i permessi richiesti da Nextcloud:

sudo mkdir -p /srv/nextcloud/data
sudo chown -R 33:33 /srv/nextcloud/data
sudo chmod 0770 /srv/nextcloud/data

Nota la pubblicazione della porta: 127.0.0.1:8080:80. Docker pubblica le porte scrivendo regole DNAT che vengono valutate prima che il pacchetto raggiunga la catena INPUT di ufw; un semplice 8080:80 espone un'istanza Nextcloud non cifrata su Internet, indipendentemente dalla configurazione di ufw. Il binding sull'interfaccia loopback la mantiene fuori dall'interfaccia pubblica. In questo modo il firewall deve consentire soltanto il proxy. Se preferisci non lasciare SSH aperto a tutta Internet, raggiungere il VPS tramite una VPN WireGuard self-hosted consente di rimuovere completamente la porta 22 dalle regole pubbliche:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Avvialo con docker compose up -d, quindi monitora docker compose logs -f app. Al primo avvio, il container copia l'intero albero dell'applicazione nel volume ed esegue l'installer; non risponde a nessuna richiesta finché l'operazione non è terminata.

TLS e reverse proxy

Installare nginx e certbot dai repository della distribuzione, creare un blocco server semplice sulla porta 80 con il server_name corretto, quindi lasciare che certbot lo riscriva. Il funzionamento della challenge HTTP-01, il timer di rinnovo e le modalità di errore sono descritti integralmente in rilascio di certificati Let's Encrypt con certbot e nginx su Ubuntu 24.04:

sudo apt install nginx certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.example.com

Certbot aggiunge le direttive ssl_certificate e il redirect da :80 a :443, quindi installa un timer systemd che rinnova il certificato ogni 90 giorni. Verificarne l'esistenza con systemctl list-timers | grep certbot: un timer di rinnovo mai abilitato è un conto alla rovescia di 90 giorni.

Il blocco proxy:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name cloud.example.com;

    # certbot manages ssl_certificate / ssl_certificate_key here

    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;

    client_max_body_size 10G;
    client_body_timeout 300s;

    location = /.well-known/carddav { return 301 /remote.php/dav; }
    location = /.well-known/caldav  { return 301 /remote.php/dav; }

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;
        proxy_request_buffering off;
        proxy_buffering off;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

Con nginx 1.25.1 e versioni successive, aggiungere http2 on;. La direttiva non esiste nella versione 1.25.0 e nginx non si avvia se la trova. Ubuntu 24.04 include una build precedente, nella quale l'equivalente è listen 443 ssl http2;. nginx -t indica quale delle due direttive è supportata dalla build installata.

Se client_max_body_size è troppo piccolo, nginx rifiuta direttamente un caricamento di grandi dimensioni con un errore 413. Se i timeout di lettura sono troppo brevi, il caricamento si interrompe a metà. I valori precedenti evitano entrambi i problemi. proxy_request_buffering off inoltra il caricamento in streaming, senza memorizzare prima l'intero file sul disco del proxy.

nginx sull'host è la soluzione più semplice per una singola applicazione. Se Nextcloud deve condividere il VPS con altri container, eseguire Traefik come reverse proxy Docker Compose per più applicazioni sposta il routing e il rilascio dei certificati nelle label dei container. Le stesse problematiche relative a client_max_body_size e ai timeout si ripresentano sotto forma di impostazioni di middleware e trasporto.

trusted_proxies e overwriteprotocol

È qui che la maggior parte delle istanze Nextcloud self-hosted presenta problemi. I sintomi sembrano non avere relazione con la causa.

X-Forwarded-Proto: https viene applicato soltanto quando la richiesta arriva da un indirizzo elencato in trusted_proxies. Se non viene applicato, Nextcloud considera la richiesta come HTTP semplice e genera URL http://. Il proxy li reindirizza a HTTPS. Il browser segue il reindirizzamento e Nextcloud genera di nuovo http://. Questo è il loop di reindirizzamento. OVERWRITEPROTOCOL: https forza lo schema in ogni caso.

Il problema di TRUSTED_PROXIES è che l'indirizzo visualizzato da Nextcloud non è 127.0.0.1. nginx viene eseguito sull'host e si connette a una porta pubblicata. Di conseguenza, il container vede il gateway del bridge Docker, un indirizzo appartenente a 172.x. Individuate la subnet effettiva:

docker network inspect nextcloud_default \
  -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}'

Inserite quel CIDR, oppure il 172.16.0.0/12 che lo comprende, in TRUSTED_PROXIES. Se l'intervallo è troppo ampio, qualsiasi client potrebbe falsificare X-Forwarded-For. Se è errato, ogni accesso risulterà provenire dall'indirizzo del gateway, la protezione contro i tentativi di forza bruta bloccherà l'intera istanza contemporaneamente e la panoramica dell'amministrazione mostrerà "La configurazione dell'header del reverse proxy non è corretta oppure state accedendo a Nextcloud da un proxy attendibile."

OVERWRITECLIURL è importante per il container cron, che non riceve richieste in ingresso da cui ricavare il nome host. Senza questa impostazione, i job in background generano link a localhost e le notifiche email contengono URL inutilizzabili.

Processi in background: cron, non AJAX

Il job runner predefinito di Nextcloud è AJAX: i job vengono eseguiti come effetto collaterale del caricamento di una pagina. Alle 04:00 nessuno naviga, quindi la scadenza del cestino, la pulizia delle versioni, la generazione delle anteprime e i nuovi tentativi delle operazioni federate si bloccano. Il primo sintomo è una directory dei dati che continua a crescere. Il servizio cron descritto sopra esegue il ciclo ufficiale di /cron.sh sugli stessi volumi. Configura Nextcloud perché lo utilizzi:

docker compose exec -u www-data app php occ background:cron

Ogni comando occ segue questo formato: docker compose exec -u www-data app php occ <command>. Conviene definire un alias.

Backup: tre elementi, oppure nessuno

Un backup del solo filesystem ripristina un'istanza non funzionante. La directory dei dati contiene i byte; Postgres contiene la cache dei file, le condivisioni, gli utenti e lo stato dell'applicazione; config.php contiene le credenziali del database, l'ID dell'istanza e il salt delle password. Se ripristini i file senza il database, Nextcloud non può visualizzarli. Se ripristini il database senza config.php, non può aprire il database. Se ripristini un database precedente su una directory dei dati più recente, ottieni condivisioni che puntano a file spostati.

Esegui il backup di tutti e tre i componenti, con l'istanza in stato quiescente:

#!/usr/bin/env bash
set -euo pipefail
cd /srv/nextcloud
DEST="/var/backups/nextcloud/$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$DEST"

occ() { docker compose exec -T -u www-data app php occ "$@"; }

occ maintenance:mode --on
trap 'occ maintenance:mode --off' EXIT

docker compose exec -T db \
  pg_dump -U nextcloud --clean --if-exists nextcloud | gzip > "$DEST/db.sql.gz"

docker compose exec -T app \
  tar -C /var/www/html -cf - config custom_apps themes > "$DEST/app.tar"

rsync -a --delete /srv/nextcloud/data/ /var/backups/nextcloud/data/

La modalità di manutenzione fa sì che il dump e la copia dei file siano coerenti tra loro. Se la ometti, prima o poi acquisirai un database che fa riferimento a un file che rsync non aveva ancora raggiunto. Lo script conserva i dump del database con timestamp, ma mantiene una sola copia mirror rotativa della directory dei dati: rsync --delete la sovrascrive a ogni esecuzione. Di conseguenza, solo il dump più recente corrisponde alla copia dei file.

Poi trasferisci il backup fuori dal server. Un backup che si trova sullo stesso VPS dei dati protetti è una copia, non un backup. restic verso l'object storage o un secondo host è la soluzione abituale; la deduplicazione gestisce la directory dei dati molto meglio di un archivio tar notturno. La procedura completa, dall'inizializzazione del repository al timer notturno e alla prova di ripristino, è descritta in backup di VPS fuori dal server con restic.

Il ripristino non consiste semplicemente nell'eseguire i passaggi al contrario. Uno stack avviato da zero esegue l'installer e scrive un nuovo config.php, un nuovo ID dell'istanza e un nuovo salt delle password. Importare il dump sopra questa nuova identità lascia sessioni e token delle condivisioni non funzionanti. Ripristina prima la vecchia identità, in questo ordine:

docker compose up -d && docker compose stop app cron    # create the volumes, then halt the app
sudo rsync -a --delete /var/backups/nextcloud/data/ /srv/nextcloud/data/
docker compose run --rm -T --entrypoint "" app \
  tar -C /var/www/html -xf - < app.tar                  # the original config.php returns
gunzip -c db.sql.gz | docker compose exec -T db psql -U nextcloud -d nextcloud
docker compose start app cron
docker compose exec -T -u www-data app php occ maintenance:mode --off
docker compose exec -T -u www-data app php occ files:scan --all

files:scan riconcilia la cache dei file con ciò che è effettivamente presente sul disco. Esegui questa procedura una volta su un VPS di prova, prima di averne bisogno. La stessa separazione tra byte su disco e metadati in Postgres vale per tutte le altre applicazioni con questa struttura. Per questo motivo, un backup di Immich che acquisisce la libreria ma non il database ripristina una timeline vuota.

Aggiornamenti: una versione principale alla volta

Nextcloud supporta l'aggiornamento di una sola versione principale alla volta. Con l'immagine Docker ufficiale, il passaggio dalla 29 alla 31 non raggiunge mai l'aggiornamento. L'entrypoint confronta le versioni principali prima di eseguire occ upgrade, stampa Can't start Nextcloud because upgrading from <installed version> to <image version> is not supported. seguito da It is only possible to upgrade one major version at a time. e termina. Il container rifiuta di avviarsi (con restart: unless-stopped continua a riavviarsi e a stampare le stesse righe), la modalità di manutenzione non viene mai attivata e i dati e il database restano invariati. Impostare il tag sulla versione principale successiva e riavviare.

La procedura di aggiornamento Docker è la seguente: eseguire un backup, modificare il tag incrementandolo di una versione principale nei servizi app e cron (da 35 a 36 quando verrà rilasciata la 36, prevista da Nextcloud per febbraio 2027), quindi eseguire docker compose pull && docker compose up -d e poi docker compose logs -f app. L'entrypoint dell'immagine rileva che il codice è più recente rispetto ai dati esistenti ed esegue direttamente occ upgrade. Non interromperlo. Quando i log smettono di mostrare nuovi messaggi, eseguire docker compose exec -u www-data app php occ status e verificare versionstring e che le app siano nuovamente abilitate.

Due regole evitano molti problemi: incrementare di una versione principale, verificare, quindi incrementare alla successiva. Non modificare mai il tag del servizio app senza modificare anche cron in modo coerente: usare due versioni diverse di Nextcloud con lo stesso database può causare la corruzione dei dati.

Gli errori che vedrai effettivamente

"La directory dei dati è leggibile da altri utenti. Modifica i permessi impostandoli su 0770, in modo che gli altri utenti non possano elencare il contenuto della directory." L'ultima cifra della modalità della directory, quella relativa agli altri utenti, non è zero. Qualsiasi bit di lettura, scrittura o esecuzione per gli altri utenti attiva questo errore. I bit del gruppo non vengono mai controllati, perché 0770 concede già al gruppo l'accesso completo. Nextcloud prova prima a eseguire chmod 0770 autonomamente e mostra un avviso solo se l'operazione non riesce; con un bind mount questo significa in genere che la directory non appartiene all'UID 33. sudo chown -R 33:33 /srv/nextcloud/data e sudo chmod 0770 /srv/nextcloud/data.

"La directory dei dati non è valida. Assicurati che nella radice della directory dei dati sia presente un file chiamato ".ncdata"." Il bind mount punta a una posizione che Nextcloud non ha mai inizializzato, il percorso contiene un errore di digitazione oppure una directory vuota appena creata è stata sostituita a un'istanza funzionante. Verifica che il percorso sull'host corrisponda alla riga del volume.

"Accesso tramite dominio non attendibile." Il nome host della richiesta non è presente in trusted_domains. NEXTCLOUD_TRUSTED_DOMAINS si applica solo durante la prima installazione; in seguito impostalo a runtime con occ config:system:set trusted_domains 1 --value=cloud.example.com.

502 Bad Gateway, con connect() failed (111: Connection refused) while connecting to upstream in /var/log/nginx/error.log. nginx non ha raggiunto alcun servizio su 127.0.0.1:8080. Il container è ancora in fase di inizializzazione (controlla docker compose logs app), è terminato (docker compose ps) oppure la riga di pubblicazione non corrisponde alla porta proxy_pass. Verifica con ss -ltnp | grep 8080.

Un ciclo di redirect oppure avvisi "non sicuro" nella panoramica dell'amministrazione. Manca OVERWRITEPROTOCOL: https oppure TRUSTED_PROXIES non contiene la subnet del gateway Docker. Consulta la sezione precedente sul proxy.

LockedException: "files/..." is locked. Con REDIS_HOST impostato, l'immagine configura Redis come backend per il locking e i lock obsoleti sono rari. Senza questa impostazione, i lock vengono memorizzati nella tabella del database oc_file_locks e una richiesta terminata durante una scrittura lascia righe residue. Prima di eliminare manualmente le righe dei lock, verifica che Redis sia effettivamente in uso: occ config:system:get memcache.locking dovrebbe restituire la classe Redis.

"Il limite di memoria PHP è inferiore al valore consigliato di 512 MB." Aumenta PHP_MEMORY_LIMIT e ricrea il container. Tieni presente l'effetto di questa modifica sul limite massimo nei casi peggiori.

Cosa si rompe su larga scala

Il primo limite si raggiunge quando la directory dei dati supera le dimensioni del volume. L'espansione di un volume su un VPS richiede il ridimensionamento del volume e l'espansione del filesystem. È molto meno problematico eseguire questa operazione in modo pianificato, prima che il volume raggiunga il 100%. Configura subito gli alert sull'utilizzo del disco.

Il secondo limite è oc_filecache. Gli elenchi dei file e le scansioni per la sincronizzazione diventano più lente all'aumentare del numero di righe. La soluzione richiede interventi sul database: mantieni Postgres su storage veloce, assegnagli memoria condivisa sufficiente ed elimina cestino e versioni tramite le impostazioni di conservazione, invece di lasciarli accumulare indefinitamente.

Il terzo limite è la generazione delle anteprime, che compete per le risorse con tutti gli altri servizi. Su una macchina di dimensioni ridotte, limita i provider delle anteprime e non eseguire mai occ preview:generate-all durante l'orario di lavoro. Se la maggior parte dei dati archiviati proviene dal rullino fotografico di un telefono, questa elaborazione delle miniature dovrebbe essere eseguita da un server fotografico dedicato. Confronto tra PhotoPrism e Immich per memoria RAM, app per telefono e comandi di backup descrive il costo di entrambe le soluzioni accanto a un'istanza Nextcloud.

Oltre questo livello, la risposta corretta è che i componenti aggiuntivi richiedono una macchina dedicata. Collabora e la ricerca full-text sono servizi residenti separati, con profili di utilizzo della memoria propri. Eseguirli sulla macchina che contiene anche l'unica copia dei file amplia il dominio di guasto senza offrire vantaggi. Se vuoi aggiungere la modifica dei documenti nel browser, i requisiti minimi di RAM e i limiti di connessione del vendor che distinguono OnlyOffice da Collabora determinano quale dei due possa essere eseguito su un VPS da 2 a 4 GB. Sposta lo storage dei file su uno storage primario compatibile con S3 quando il volume non è più adatto alle dimensioni richieste. Tieni presente che questo rende i backup più difficili, non più semplici: il database conserva ancora i metadati e deve essere esportato insieme al bucket.

Quando l'istanza serve utenti reali, installa Uptime Kuma davanti a essa, così riceverai una notifica del downtime prima dei client di sincronizzazione. Un cloud privato si integra bene con il tuo server di posta, mentre, se preferisci non collegare i servizi manualmente, Cloudron, CasaOS e Coolify confronta le piattaforme che automatizzano questa attività. Se il prossimo componente dell'elenco è un motore di ricerca self-hosted, aspettati un problema di natura diversa da quelli descritti sopra: gli errori 429 di SearXNG sono causati dal suo rate limiter oppure dai motori upstream che bloccano l'indirizzo IP del VPS. Solo il log permette di stabilire quale delle due cause sia responsabile.

FAQ

È possibile eseguire Nextcloud su SQLite invece che su Postgres?

Sì, e l'immagine ufficiale lo consente, ma un singolo client di sincronizzazione desktop che invia richieste in parallelo raggiungerà SQLSTATE[HY000]: General error: 5 database is locked e produrrà errori HTTP 500. SQLite applica un blocco di scrittura a livello di database, mentre Nextcloud scrive continuamente: blocchi dei file, righe delle attività e stato dei job. Iniziare con Postgres o MariaDB; occ db:convert-type esiste, ma sui dati in produzione è una migrazione lunga e indivisibile.

Quanta RAM richiede realmente un VPS Nextcloud?

Dimensionare in base alla concorrenza, non al numero di utenti. La memoria residente nel caso peggiore è approssimativamente pari al numero di richieste concorrenti moltiplicato per PHP_MEMORY_LIMIT, più i buffer condivisi di Postgres, un backend per connessione e l'eventuale picco dovuto alla generazione delle anteprime. Un sistema con 2 GB può eseguire un'istanza domestica di piccole dimensioni se si limitano le anteprime e si aggiunge lo swap; con Collabora o la ricerca full-text occorre considerare un secondo insieme di servizi residenti.

Perché i caricamenti di grandi dimensioni falliscono dietro il reverse proxy nginx?

Di solito la causa è riconducibile a due impostazioni del proxy. Se client_max_body_size mantiene il valore predefinito di 1 MB, nginx rifiuta immediatamente qualsiasi richiesta più grande con un errore 413 (Request Entity Too Large). L'errore compare nel log degli errori di nginx, non come file parziale. Valori ridotti di proxy_read_timeout / proxy_send_timeout interrompono i trasferimenti lunghi a metà. Impostare entrambi su valori generosi, configurare proxy_request_buffering off per lo streaming invece che per lo spool e aumentare PHP_UPLOAD_LIMIT sul container dell'applicazione in modo che corrisponda.

Perché Nextcloud esegue un redirect in loop o mostra un avviso sul reverse proxy?

Il container non vede nginx a 127.0.0.1, ma vede il gateway della rete bridge Docker, in un punto compreso in 172.x. Quando quell'indirizzo manca da TRUSTED_PROXIES, l'header X-Forwarded-Proto: https viene ignorato, Nextcloud genera URL http:// e il proxy li reindirizza nuovamente. Impostare TRUSTED_PROXIES sulla subnet bridge effettiva e fissare OVERWRITEPROTOCOL: https.

È possibile aggiornare Nextcloud direttamente dalla versione 29 alla 31?

No. Nextcloud supporta una sola versione principale per ogni aggiornamento. Nell'immagine Docker ufficiale, l'entrypoint controlla le versioni principali prima di eseguire occ upgrade, stampa It is only possible to upgrade one major version at a time. ed esce. Di conseguenza il container non si avvia e i dati e il database restano invariati. Impostare il tag su 30: eseguire il backup, incrementare di una versione principale il tag su entrambi i servizi app e cron, docker compose pull && docker compose up -d, verificare con occ status, quindi ripetere la procedura.