Nextcloud installeren op VPS met Docker Compose
Bouw een robuuste Nextcloud-omgeving met Docker, Postgres en Redis. Leer hoe u TLS-encryptie configureert en een betrouwbare back-upstrategie opzet voor uw data op Ubuntu.
Wat u daadwerkelijk bouwt
Deze handleiding draait Nextcloud op een VPS met Docker Compose, plaatst Let's Encrypt TLS ervoor en zet een back-up op die daadwerkelijk herstelt. Vier containers en een proxy: de officiële nextcloud-image die luistert op loopback, Postgres die alle bestandsmetadata bevat, Redis die de bestandsvergrendelingen beheert, een tweede kopie van de Nextcloud-image die uitsluitend de cron-loop uitvoert, en nginx op de host die TLS voor dit alles afhandelt. De installatie zelf duurt twintig minuten, en dat is niet het belangrijkste onderdeel. Twee beslissingen in het eerste uur bepalen of u over een jaar nog over uw bestanden beschikt: een echte database in plaats van SQLite, en een back-up die de datamap, de database en config.php als één consistente set vastlegt.
Dit gaat uit van Ubuntu 24.04 LTS of Debian 13, Docker Engine met de Compose v2-plugin geïnstalleerd vanuit de eigen repository van Docker, en een DNS A-record (plus AAAA als u IPv6 heeft) dat al naar cloud.example.com op de VPS wijst. Dit alles vereist een server die u zelf beheert; er is geen mogelijkheid om TLS-termination en een database-dump uit te voeren op de SaaS van een andere partij.
Dimensionering: wat verbruikt daadwerkelijk het geheugen
Het geheugengebruik van Nextcloud wordt gedomineerd door drie factoren, en geen daarvan is "Nextcloud" als zodanig.
PHP-workers. De -apache-image bedient elk gelijktijdig verzoek vanuit een worker-proces dat een PHP-interpreter bevat. Elke worker kan groeien tot PHP_MEMORY_LIMIT voordat PHP het verzoek beëindigt. Uw worst-case resident geheugen is ongeveer gelijktijdige verzoeken × de geheugenlimiet, en een desktop-synchronisatieclient opent meerdere parallelle verbindingen per gebruiker. Concurrency, niet het aantal gebruikers, bepaalt de bovengrens.
De database. Postgres splitst een backend per verbinding en houdt gedeelde buffers in het geheugen. De werkset schaalt met het aantal bestanden, niet met het aantal bytes: oc_filecache bevat een rij per bestand per gebruiker. Honderdduizend kleine bestanden vormen een zwaardere database dan honderd grote bestanden.
Preview-generatie. Bij het genereren van een thumbnail wordt de bronafbeelding in het geheugen gedecodeerd op volledige resolutie. Videopreviews roepen ffmpeg aan. Het uitvoeren van occ preview:generate-all voert die piek herhaaldelijk achter elkaar uit en is de meest voorkomende manier om een kleine VPS in de OOM-killer te dwingen.
Redis is relatief goedkoop. Alles wat u later toevoegt, zoals Collabora, full-text search of een antivirusscanner, is een afzonderlijke residente service met een eigen voetafdruk. Neem dit op in uw dimensioneringsplan voordat u het inschakelt.
De knoppen waar u aan kunt draaien als u weinig RAM heeft: verlaag PHP_MEMORY_LIMIT, beperk preview_max_x / preview_max_y / preview_max_filesize_image, beperk enabledPreviewProviders tot de formaten die u daadwerkelijk bekijkt, en stel trashbin_retention_obligation en versions_retention_obligation zo in dat de datadirectory niet ongemerkt groeit tot meerdere malen de grootte van uw bestanden. Voeg een swap-bestand toe. Swap is traag, maar een OOM-kill tijdens een upgrade is erger.
Waarom SQLite problemen veroorzaakt
Nextcloud wordt geleverd met ondersteuning voor SQLite en de officiële image zal dit zonder problemen gebruiken. Doe dit niet. SQLite serialiseert schrijfacties met een database-brede lock: slechts één schrijver tegelijk voor het gehele bestand. Nextcloud schrijft constant gegevens weg, zoals file locks, activiteitsregels, cache-items en de status van taken. Een enkele desktopclient die een mappenstructuur synchroniseert, genereert bovendien veel parallelle verzoeken. Onder dit patroon krijgt u te maken met SQLSTATE[HY000]: General error: 5 database is locked en HTTP 500-fouten, en de fout treedt precies op het moment op dat de instantie nuttig begint te worden.
Een latere conversie is mogelijk met occ db:convert-type, maar dit is een langdurige alles-of-niets migratie op een actieve dataset. Begin direct met Postgres of MariaDB.
Het Compose-bestand
Plaats dit in /srv/nextcloud/compose.yaml, met secrets in een bijbehorend .env-bestand met modus 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:31-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:31-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:Pin de major-versie en controleer de huidige versie op Docker Hub voordat u 31 letterlijk kopieert. latest zal u bij een toekomstige docker compose pull over een major-grens tillen, en Nextcloud ondersteunt dat niet.
De datamap is bewust een bind mount en geen named volume: een pad waar u direct een back-uptool op kunt richten is waardevoller dan netheid. Maak deze aan met de UID www-data van de image en de rechten die Nextcloud vereist:
sudo mkdir -p /srv/nextcloud/data
sudo chown -R 33:33 /srv/nextcloud/data
sudo chmod 0770 /srv/nextcloud/dataLet op de poortpublicatie: 127.0.0.1:8080:80. Docker publiceert poorten door DNAT-regels te schrijven die worden geëvalueerd voordat de INPUT-chain van ufw het pakket ooit ziet; een kale 8080:80 zet een ongecodeerde Nextcloud op het openbare internet, ongeacht wat ufw zegt. Door te binden aan loopback blijft deze van de openbare interface af. De firewall hoeft dan alleen de proxy toe te staan, en als u SSH liever niet openstelt voor het hele internet, kunt u via het bereiken van de VPS via een zelfgehoste WireGuard VPN poort 22 volledig uit de openbare regels verwijderen:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enableStart het geheel met docker compose up -d en bekijk vervolgens docker compose logs -f app. Bij de eerste opstart wordt de volledige applicatiestructuur naar het volume gekopieerd en de installer uitgevoerd; de container reageert nergens op totdat dit proces is voltooid.
TLS en de reverse proxy
Installeer nginx en certbot vanuit de distributie, maak een standaard server block voor poort 80 met de juiste server_name, en laat certbot dit vervolgens herschrijven. De werking van de HTTP-01 challenge, de vernieuwingstimer en de faalmodi worden volledig behandeld in het uitgeven van Let's Encrypt-certificaten met certbot en nginx op Ubuntu 24.04:
sudo apt install nginx certbot python3-certbot-nginx
sudo certbot --nginx -d cloud.example.comCertbot voegt de ssl_certificate-regels en de :80 → :443-redirect toe, en installeert een systemd-timer die het 90-dagen-certificaat vernieuwt. Controleer of deze bestaat met systemctl list-timers | grep certbot; een vernieuwingstimer die nooit is ingeschakeld, werkt als een tijdbom van 90 dagen.
Het proxy-blok zelf:
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;
}
}Voeg op nginx 1.25 en nieuwer http2 on; toe. Ubuntu 24.04 levert een oudere build waarbij het equivalent listen 443 ssl http2; is. nginx -t vertelt u welke optie uw build accepteert.
client_max_body_size en de lange read timeouts voorkomen dat grote uploads halverwege afbreken. proxy_request_buffering off streamt de upload door in plaats van het volledige bestand eerst naar de schijf van de proxy te schrijven.
nginx op de host is de eenvoudigste oplossing die werkt voor één applicatie. Als Nextcloud de VPS gaat delen met andere containers, verplaatst het draaien van Traefik als een Docker Compose reverse proxy voor meerdere applicaties de routering en certificaatuitgifte naar container-labels, waarbij dezelfde client_max_body_size- en timeout-overwegingen daar terugkeren als middleware- en transportinstellingen.
trusted_proxies en overwriteprotocol
Dit is het punt waar de meeste zelfgehoste Nextcloud-instanties de fout in gaan, waarbij de symptomen vaak ongerelateerd lijken aan de oorzaak.
X-Forwarded-Proto: https wordt alleen gerespecteerd wanneer het verzoek afkomstig is van een adres dat in trusted_proxies staat vermeld. Wanneer dit niet wordt gerespecteerd, gaat Nextcloud ervan uit dat het verzoek gewone HTTP is en genereert het http://-URL's; de proxy stuurt deze door naar HTTPS; de browser volgt; Nextcloud genereert opnieuw http://. Dat is de redirect-loop. OVERWRITEPROTOCOL: https dwingt het schema af, ongeacht de situatie.
De valkuil bij TRUSTED_PROXIES is dat het adres dat Nextcloud ziet, niet 127.0.0.1 is. nginx draait op de host en maakt verbinding met een gepubliceerde poort, waardoor de container de Docker-bridge-gateway ziet, iets in 172.x. Zoek het juiste subnet op:
docker network inspect nextcloud_default \
-f '{{range .IPAM.Config}}{{.Subnet}}{{end}}'Plaats die CIDR (of het overkoepelende 172.16.0.0/12) in TRUSTED_PROXIES. Als u dit te ruim instelt, kan elke client X-Forwarded-For spoofen; als u dit onjuist instelt, lijkt elke login afkomstig van het gateway-adres, blokkeert de brute-force-beveiliging uw volledige instantie in één keer en toont het admin-overzicht: "De configuratie van de reverse proxy-header is onjuist, of u benadert Nextcloud via een vertrouwde proxy."
OVERWRITECLIURL is van belang voor de cron-container, die geen inkomend verzoek heeft om een hostnaam uit af te leiden. Zonder deze instelling genereren achtergrondtaken koppelingen naar localhost en bevatten e-mailnotificaties onbruikbare URL's.
Achtergrondtaken: cron in plaats van AJAX
De standaard job-runner van Nextcloud is AJAX: taken worden uitgevoerd als bijproduct wanneer iemand een pagina laadt. Omdat er om 04:00 uur niemand op de site surft, blijven het verwijderen van prullenbakbestanden, het opschonen van versies, het genereren van previews en federated retries liggen. Het eerste symptoom hiervan is een datamap die blijft groeien. De cron-service hierboven voert de officiële /cron.sh-loop uit op dezelfde volumes. Instrueer Nextcloud om dit te verwachten:
docker compose exec -u www-data app php occ background:cronElk occ-commando volgt dit patroon: docker compose exec -u www-data app php occ <command>. Het is aan te raden hiervoor een alias aan te maken.
Backups: drie onderdelen, of geen
Een backup van alleen het bestandssysteem herstelt naar een defecte instantie. De data-directory bevat de bytes; Postgres bevat de file cache, shares, gebruikers en de applicatiestatus; config.php bevat de database-inloggegevens, het instance ID en de password salt. Herstel de bestanden zonder de database en Nextcloud kan ze niet zien. Herstel de database zonder config.php en het kan de database niet openen. Herstel een oude database op een nieuwere data-directory en u krijgt shares die verwijzen naar bestanden die zijn verplaatst.
Maak een backup van alle drie, vanaf een gepauzeerde instantie:
#!/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/De onderhoudsmodus zorgt ervoor dat de dump en de bestandskopie met elkaar overeenstemmen. Slaat u dit over, dan legt u uiteindelijk een database vast die verwijst naar een bestand dat de rsync nog niet had bereikt. Let op: het script bewaart database-dumps met een tijdstempel, maar slechts één doorlopende mirror van de data-directory; rsync --delete overschrijft deze bij elke run, waardoor alleen de nieuwste dump bij de bestandskopie hoort.
Verplaats de backup vervolgens van de server. Een backup die op dezelfde VPS staat als de bron, is een kopie, geen backup. restic naar object storage of een tweede host is de gebruikelijke oplossing, en de deduplicatie daarvan gaat veel beter om met de data-directory dan een dagelijkse tarball. De volledige configuratie, van repository init tot de dagelijkse timer en de restore-oefening, staat in off-box VPS backups met restic.
Een restore is niet simpelweg het omgekeerde proces. Een vers gestarte stack voert de installer uit en schrijft een gloednieuwe config.php, een nieuw instance ID en password salt. Het importeren van de dump bovenop die nieuwe identiteit resulteert in kapotte sessies en share tokens. Plaats eerst de oude identiteit terug, in deze volgorde:
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 --allfiles:scan brengt de file cache in overeenstemming met wat er daadwerkelijk op de schijf staat. Oefen dit eenmaal op een reserve-VPS voordat u het echt nodig heeft. Dezelfde scheiding tussen bytes op schijf en metadata in Postgres geldt voor elke andere applicatie van dit type, en dat is waarom een Immich-backup die de library maar niet de database vastlegt, herstelt naar een lege tijdlijn.
Upgrades: één grote versie per keer
Nextcloud ondersteunt het upgraden van precies één grote versie per keer. Een sprong van 29 naar 31 verloopt niet correct; het resulteert in Exception: Updates between multiple major versions and downgrades are unsupported. en laat u achter in de onderhoudsmodus.
De Docker-upgrade verloopt als volgt: maak een back-up, wijzig de tag van 31 naar 32 in zowel de app- als de cron-service, voer daarna docker compose pull && docker compose up -d uit en vervolgens docker compose logs -f app. De entrypoint van de image detecteert de nieuwere code ten opzichte van de bestaande data en voert zelf occ upgrade uit. Onderbreek dit proces niet. Zodra de logs stilvallen, voert u docker compose exec -u www-data app php occ status uit en controleert u versionstring en of de apps weer ingeschakeld zijn.
Twee regels die u behoeden voor problemen: verhoog één grote versie, verifieer de werking en verhoog daarna pas de volgende. Wijzig nooit de tag van de app-service zonder de cron-service aan te passen naar dezelfde versie; twee verschillende Nextcloud-versies die gebruikmaken van één database leiden tot corruptie.
De foutmeldingen die u daadwerkelijk zult zien
"Your data directory is readable by other users. Please change the permissions to 0770." De bind-mounted map heeft leesrechten voor de groep of voor iedereen. sudo chmod 0770 /srv/nextcloud/data en sudo chown -R 33:33 /srv/nextcloud/data.
"Your data directory is invalid. Ensure there is a file called .ocdata in the root." De bind mount verwijst naar een locatie die nooit door Nextcloud is geïnitialiseerd, er staat een typefout in het pad, of er is een nieuwe lege map onder een werkende instantie geplaatst. Controleer of het pad op de host overeenkomt met de volume-regel.
"Access through untrusted domain." De hostnaam in het verzoek staat niet in trusted_domains. NEXTCLOUD_TRUSTED_DOMAINS is alleen van toepassing bij de eerste installatie; pas het daarna live aan: occ config:system:set trusted_domains 1 --value=cloud.example.com.
502 Bad Gateway, met connect() failed (111: Connection refused) while connecting to upstream in /var/log/nginx/error.log. nginx kon niets bereiken op 127.0.0.1:8080. Of de container is nog bezig met initialiseren (controleer docker compose logs app), de container is afgesloten (docker compose ps), of de publish-regel komt niet overeen met de proxy_pass poort. Bevestig dit met ss -ltnp | grep 8080.
Een redirect-loop, of "insecure" waarschuwingen in het admin-overzicht. OVERWRITEPROTOCOL: https ontbreekt, of TRUSTED_PROXIES bevat niet het Docker-gateway-subnet. Zie de sectie over de proxy hierboven.
LockedException: "files/..." is locked. Met REDIS_HOST ingesteld, configureert de image Redis als de locking-backend en komen verouderde locks zelden voor. Zonder deze instelling bevinden locks zich in de databasetabel oc_file_locks en laat een verzoek dat halverwege het schrijven wordt afgebroken rijen achter. Controleer of Redis daadwerkelijk in gebruik is; occ config:system:get memcache.locking zou de Redis-klasse moeten retourneren voordat u handmatig lock-rijen verwijdert.
"The PHP memory limit is below the recommended value of 512MB." Verhoog PHP_MEMORY_LIMIT en maak de container opnieuw aan. Houd rekening met de impact hiervan op uw maximale geheugengebruik in het slechtste geval.
Wat er misgaat bij schaalvergroting
De eerste barrière is de datamap die groter wordt dan het volume. Het vergroten van een volume op een VPS vereist een resize en een uitbreiding van het bestandssysteem; dit is veel minder belastend wanneer het gepland gebeurt dan wanneer de schijf voor 100% vol is. Stel daarom nu waarschuwingen in voor schijfgebruik, niet pas later.
De tweede barrière is oc_filecache. Bestandsoverzichten en synchronisatiescans vertragen naarmate het aantal rijen toeneemt. De oplossing is database-onderhoud: bewaar Postgres op snelle opslag, zorg dat het voldoende gedeeld geheugen kan gebruiken en verwijder oude versies en overbodige data via retentie-instellingen in plaats van deze oneindig te laten ophopen.
De derde barrière is het genereren van previews dat concurreert met alle andere processen. Beperk op een kleine server het aantal preview-providers en voer occ preview:generate-all nooit uit tijdens kantooruren. Als de camerabestanden van een telefoon het grootste deel van uw opslag beslaan, hoort dat thumbnail-proces thuis op een specifieke fotoserver. PhotoPrism en Immich vergeleken op RAM, telefoon-apps en backup-commando's behandelt wat beide opties kosten in vergelijking met een Nextcloud-server.
Daarbuiten is het eerlijke antwoord dat extra functies een eigen machine vereisen. Collabora en full-text search zijn afzonderlijke residente services met hun eigen geheugenprofielen. Deze op dezelfde server plaatsen als uw enige kopie van uw bestanden vergroot het risico bij uitval zonder enig voordeel. Als u documenten in de browser wilt bewerken, bepalen de door de leverancier gestelde RAM-eisen en verbindingslimieten die OnlyOffice van Collabora onderscheiden welke optie een VPS met 2 tot 4 GB RAM überhaupt kan draaien. Verplaats bestandsopslag naar S3-compatibele primaire opslag wanneer het volume niet langer voldoet, maar houd er rekening mee dat dit backups moeilijker maakt, niet makkelijker: de database bevat nog steeds de metadata en moet synchroon met de bucket worden gedumpt.
Zodra de instantie echte gebruikers bedient, plaatst u Uptime Kuma ervoor, zodat u op de hoogte bent van downtime voordat de synchronisatie-clients dat zijn. Een private cloud vormt een goede combinatie met uw eigen mailserver. Als u services liever niet handmatig aan elkaar koppelt, vergelijken Cloudron, CasaOS en Coolify de platformen die dit voor u doen. Als een zelfgehoste zoekmachine de volgende stap is, verwacht dan een ander type probleem dan hierboven genoemd: 429-fouten in SearXNG worden veroorzaakt door de eigen rate limiter of doordat upstream-engines uw VPS-IP blokkeren; alleen het logbestand vertelt u welke van de twee het is.
FAQ
Kan ik Nextcloud op SQLite draaien in plaats van Postgres?
Dat kan, en de officiële image staat dit toe, maar een enkele desktop-synchronisatieclient die parallelle verzoeken verstuurt, zal leiden tot SQLSTATE[HY000]: General error: 5 database is locked en HTTP 500-fouten. SQLite hanteert een database-brede schrijfvergrendeling, terwijl Nextcloud constant schrijft naar bestandsvergrendelingen, activiteitenrijen en de status van taken. Begin direct met Postgres of MariaDB; occ db:convert-type bestaat wel, maar het is een langdurige migratie die alles of niets is bij live data.
Hoeveel RAM heeft een Nextcloud VPS daadwerkelijk nodig?
Kijk naar gelijktijdigheid, niet naar het aantal gebruikers. Het worst-case resident geheugengebruik is grofweg het aantal gelijktijdige verzoeken vermenigvuldigd met PHP_MEMORY_LIMIT, plus de gedeelde buffers van Postgres en één backend per verbinding, plus de pieken die ontstaan bij het genereren van voorbeelden. Een server met 2 GB RAM kan een kleine huishoudelijke instantie draaien als u voorbeelden beperkt en swap toevoegt; voeg Collabora of full-text search toe en u moet rekening houden met een tweede set resident services.
Waarom mislukken grote uploads achter de nginx reverse proxy?
Twee instellingen op de proxy verklaren dit meestal: client_max_body_size staat standaard op 1 MB en kapt het verzoek af, en korte proxy_read_timeout / proxy_send_timeout waarden verbreken lange overdrachten halverwege. Stel beide ruim in, zet proxy_request_buffering off op streamen in plaats van spoolen, en verhoog PHP_UPLOAD_LIMIT op de applicatiecontainer zodat deze overeenkomt.
Waarom komt Nextcloud in een redirect-loop of geeft het waarschuwingen over de reverse proxy?
De container ziet nginx niet op 127.0.0.1, maar ziet de Docker bridge gateway, ergens in 172.x. Wanneer dat adres ontbreekt in TRUSTED_PROXIES, wordt de X-Forwarded-Proto: https-header genegeerd, genereert Nextcloud http://-URL's en kaatst de proxy deze terug. Stel TRUSTED_PROXIES in op het werkelijke bridge-subnet en zet OVERWRITEPROTOCOL: https vast.
Kan ik Nextcloud direct upgraden van 29 naar 31?
Nee. Nextcloud ondersteunt één grote versie per upgrade; overslaan stopt bij Updates between multiple major versions and downgrades are unsupported., waardoor de instantie in de onderhoudsmodus blijft staan. Maak een back-up, verhoog de tag met één grote versie op zowel de app- als de cron-services, voer docker compose pull && docker compose up -d uit, verifieer met occ status en herhaal dit proces.