SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-25

Nextcloud auf VPS mit Docker Compose einrichten

Installieren Sie Nextcloud sicher auf einem VPS mit Docker Compose, Postgres und Redis. Diese Anleitung zeigt die korrekte TLS-Konfiguration und ein zuverlässiges Backup-Skript.

Was Sie tatsächlich aufbauen

Diese Anleitung betreibt Nextcloud auf einem VPS mit Docker Compose, schaltet Let's Encrypt TLS davor und richtet ein Backup ein, das sich tatsächlich wiederherstellen lässt. Vier Container und ein Proxy: das offizielle nextcloud-Image, das auf dem Loopback-Interface lauscht, Postgres für sämtliche Dateimetadaten, Redis für die Dateisperren, eine zweite Instanz des Nextcloud-Images ausschließlich für den Cron-Job sowie nginx auf dem Host, der die TLS-Terminierung für alle Dienste übernimmt. Die Installation selbst dauert zwanzig Minuten, doch darauf kommt es nicht an. Zwei Entscheidungen in der ersten Stunde bestimmen, ob Ihre Dateien auch in einem Jahr noch vorhanden sind: eine echte Datenbank statt SQLite und ein Backup, das das Datenverzeichnis, die Datenbank und config.php als einen konsistenten Satz erfasst.

Dies setzt Ubuntu 24.04 LTS oder Debian 13, die Docker Engine mit dem Compose v2-Plugin aus dem offiziellen Docker-Repository sowie einen bereits auf den VPS zeigenden DNS A-Eintrag (plus AAAA bei vorhandenem IPv6) für cloud.example.com voraus. All dies erfordert einen Server unter Ihrer Kontrolle; TLS-Terminierung und Datenbank-Dumps lassen sich nicht auf einer fremden SaaS-Plattform umsetzen.

Dimensionierung: Was verbraucht tatsächlich Arbeitsspeicher

Der Speicherverbrauch von Nextcloud wird von drei Faktoren dominiert, von denen keiner direkt "Nextcloud" selbst ist.

PHP-Worker. Das -apache-Image bedient jede gleichzeitige Anfrage über einen Worker-Prozess, der einen PHP-Interpreter enthält. Jeder Worker kann bis zu PHP_MEMORY_LIMIT belegen, bevor PHP die Anfrage abbricht. Ihr Worst-Case-Speicherbedarf entspricht in etwa gleichzeitige Anfragen × Speicherlimit. Der Desktop-Sync-Client öffnet pro Benutzer mehrere parallele Verbindungen. Nicht die Anzahl der Benutzer, sondern die Gleichzeitigkeit bestimmt den Bedarf.

Die Datenbank. Postgres startet pro Verbindung einen Backend-Prozess und hält Shared Buffers im Arbeitsspeicher. Das Working-Set skaliert mit der Anzahl der Dateien, nicht mit der Anzahl der Bytes: oc_filecache führt eine Zeile pro Datei und Benutzer. Hunderttausend kleine Dateien belasten die Datenbank stärker als hundert große.

Vorschaubilder-Generierung. Beim Erstellen eines Thumbnails wird das Quellbild in voller Auflösung in den Arbeitsspeicher dekodiert. Videovorschauen nutzen ffmpeg. Die Ausführung von occ preview:generate-all führt diese Lastspitzen wiederholt hintereinander aus und ist der häufigste Grund, warum ein kleiner VPS durch den OOM-Killer beendet wird.

Redis ist vergleichsweise ressourcenschonend. Alles, was Sie später hinzufügen – Collabora, Volltextsuche, ein Antiviren-Scanner –, ist ein eigenständiger Dienst mit einem eigenen Speicherbedarf. Planen Sie dies bei der Dimensionierung ein, bevor Sie die Funktionen aktivieren.

Die Stellschrauben bei knappem RAM: Reduzieren Sie PHP_MEMORY_LIMIT, begrenzen Sie preview_max_x / preview_max_y / preview_max_filesize_image, beschränken Sie enabledPreviewProviders auf die Formate, die Sie tatsächlich verwenden, und konfigurieren Sie trashbin_retention_obligation sowie versions_retention_obligation so, dass das Datenverzeichnis nicht unbemerkt auf ein Vielfaches der Dateigröße anwächst. Richten Sie eine Swap-Datei ein. Swap ist langsam, aber ein OOM-Kill während eines Upgrades ist schlimmer.

Warum SQLite zu Problemen führt

Nextcloud wird mit SQLite-Unterstützung ausgeliefert und das offizielle Image verwendet diese standardmäßig. Verwenden Sie diese jedoch nicht. SQLite serialisiert Schreibvorgänge durch eine datenbankweite Sperre: Es kann immer nur ein Schreibvorgang gleichzeitig auf die gesamte Datei zugreifen. Nextcloud schreibt jedoch ständig Daten, wie Dateisperren, Aktivitätseinträge, Cache-Daten, Job-Status und Synchronisierungsanfragen eines Desktop-Clients, die viele parallele Anfragen erzeugen. Bei diesem Zugriffsmuster treten SQLSTATE[HY000]: General error: 5 database is locked und HTTP 500-Fehler auf. Das Versagen tritt genau dann ein, wenn die Instanz beginnt, produktiv genutzt zu werden.

Eine spätere Konvertierung ist mit occ db:convert-type möglich, stellt jedoch eine langwierige Alles-oder-Nichts-Migration auf einem aktiven Datensatz dar. Beginnen Sie direkt mit Postgres oder MariaDB.

Die Compose-Datei

Speichern Sie dies in /srv/nextcloud/compose.yaml, mit den Secrets in einer gleichnamigen .env-Datei mit den Berechtigungen 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:

Fixieren Sie die Major-Version und prüfen Sie die aktuelle Version auf Docker Hub, bevor Sie 31 unverändert übernehmen. latest führt bei einem zukünftigen docker compose pull zu einem Versionssprung über eine Major-Grenze hinweg, was von Nextcloud nicht unterstützt wird.

Das Datenverzeichnis ist bewusst ein Bind-Mount und kein Named-Volume: Ein Pfad, auf den ein Backup-Tool direkt zugreifen kann, ist wertvoller als bloße Ordnung. Erstellen Sie das Verzeichnis mit der UID www-data des Images und den von Nextcloud geforderten Berechtigungen:

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

Beachten Sie die Port-Freigabe: 127.0.0.1:8080:80. Docker veröffentlicht Ports durch das Schreiben von DNAT-Regeln, die ausgewertet werden, bevor die INPUT-Chain von ufw das Paket überhaupt erreicht. Ein einfaches 8080:80 stellt ein unverschlüsseltes Nextcloud ins öffentliche Internet, ungeachtet der ufw-Regeln. Die Bindung an das Loopback-Interface hält den Dienst vom öffentlichen Netzwerk fern. Die Firewall muss dann nur noch den Proxy zulassen. Wenn Sie SSH nicht für das gesamte Internet offen lassen möchten, können Sie den VPS über ein selbst gehostetes WireGuard VPN erreichen und Port 22 vollständig aus den öffentlichen Regeln entfernen:

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

Starten Sie den Dienst mit docker compose up -d und beobachten Sie anschließend docker compose logs -f app. Beim ersten Start wird der gesamte Anwendungsbaum in das Volume kopiert und der Installer ausgeführt; der Container antwortet erst, wenn dieser Vorgang abgeschlossen ist.

TLS und der Reverse Proxy

Installieren Sie nginx und certbot aus den Paketquellen der Distribution, erstellen Sie einen einfachen Server-Block für Port 80 mit dem korrekten server_name und lassen Sie diesen anschließend von certbot umschreiben. Die Mechanismen der HTTP-01-Challenge, der Erneuerungs-Timer und die Fehlerzustände werden ausführlich in Ausstellen von Let's Encrypt-Zertifikaten mit certbot und nginx unter Ubuntu 24.04 behandelt:

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

Certbot fügt die ssl_certificate-Zeilen sowie den Redirect von :80 auf :443 hinzu und installiert einen systemd-Timer, der das 90-Tage-Zertifikat erneuert. Überprüfen Sie dessen Existenz mit systemctl list-timers | grep certbot; ein nicht aktivierter Erneuerungs-Timer ist eine 90-Tage-Zeitbombe.

Der Proxy-Block selbst:

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;
    }
}

Fügen Sie bei nginx 1.25 und neuer http2 on; hinzu. Ubuntu 24.04 liefert eine ältere Version aus, bei der das Äquivalent listen 443 ssl http2; lautet. nginx -t zeigt Ihnen an, welche Variante Ihr Build akzeptiert.

client_max_body_size und die langen Read-Timeouts verhindern, dass große Uploads vorzeitig abbrechen. proxy_request_buffering off streamt den Upload direkt durch, anstatt die gesamte Datei zuerst auf die Festplatte des Proxys zu schreiben.

nginx auf dem Host ist die einfachste funktionierende Lösung für eine einzelne Anwendung. Wenn Nextcloud sich den VPS mit anderen Containern teilen soll, verlagert Betrieb von Traefik als Docker Compose Reverse Proxy für mehrere Anwendungen das Routing und die Zertifikatsausstellung in Container-Labels; die gleichen Bedenken hinsichtlich client_max_body_size und Timeouts treten dort als Middleware- und Transport-Einstellungen erneut auf.

trusted_proxies und overwriteprotocol

Hier machen die meisten selbst gehosteten Nextcloud-Instanzen Fehler, wobei die Symptome oft nichts mit der eigentlichen Ursache zu tun haben.

X-Forwarded-Proto: https wird nur berücksichtigt, wenn die Anfrage von einer Adresse stammt, die in trusted_proxies aufgeführt ist. Wenn dies nicht der Fall ist, geht Nextcloud davon aus, dass die Anfrage über unverschlüsseltes HTTP erfolgt, und generiert http://-URLs. Der Proxy leitet diese auf HTTPS um, der Browser folgt der Weiterleitung, und Nextcloud generiert erneut http://. Dies führt zu einer Redirect-Schleife. OVERWRITEPROTOCOL: https erzwingt das Protokoll unabhängig davon.

Die Falle bei TRUSTED_PROXIES besteht darin, dass die Adresse, die Nextcloud sieht, nicht 127.0.0.1 ist. nginx läuft auf dem Host und verbindet sich mit einem veröffentlichten Port, sodass der Container das Docker-Bridge-Gateway sieht, also eine Adresse aus 172.x. Ermitteln Sie das tatsächliche Subnetz:

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

Tragen Sie diese CIDR (oder das abdeckende 172.16.0.0/12) in TRUSTED_PROXIES ein. Ist der Bereich zu weit gefasst, kann jeder Client X-Forwarded-For fälschen. Ist er falsch konfiguriert, erscheint jeder Login so, als käme er von der Gateway-Adresse. Der Brute-Force-Schutz sperrt dann die gesamte Instanz auf einmal, und die Admin-Übersicht zeigt die Meldung: "Die Konfiguration des Reverse-Proxy-Headers ist falsch, oder Sie greifen über einen nicht vertrauenswürdigen Proxy auf Nextcloud zu."

OVERWRITECLIURL ist für den cron-Container wichtig, da dieser keine eingehende Anfrage hat, von der er einen Hostnamen ableiten könnte. Ohne diese Einstellung generieren Hintergrundprozesse Links zu localhost, und E-Mail-Benachrichtigungen enthalten unbrauchbare URLs.

Hintergrund-Jobs: cron statt AJAX

Der Standard-Job-Runner von Nextcloud ist AJAX: Jobs werden als Nebeneffekt ausgeführt, wenn ein Benutzer eine Seite lädt. Da um 04:00 Uhr niemand surft, bleiben das Löschen von Papierkörben, die Bereinigung von Versionen, die Erstellung von Vorschaubildern und föderierte Wiederholungsversuche hängen. Das erste Symptom ist ein Datenverzeichnis, das unaufhörlich wächst. Der oben genannte cron-Dienst führt die offizielle /cron.sh-Schleife auf denselben Volumes aus. Konfigurieren Sie Nextcloud so, dass es diesen Dienst verwendet:

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

Jeder occ-Befehl folgt diesem Schema: docker compose exec -u www-data app php occ <command>. Es lohnt sich, dafür einen Alias anzulegen.

Backups: drei Dinge oder gar keine

Ein reines Dateisystem-Backup führt bei der Wiederherstellung zu einer defekten Instanz. Das Datenverzeichnis enthält die Bytes; Postgres verwaltet den Datei-Cache, Freigaben, Benutzer und den Anwendungsstatus; config.php speichert die Datenbank-Zugangsdaten, die Instanz-ID und das Passwort-Salt. Stellen Sie die Dateien ohne die Datenbank wieder her, kann Nextcloud sie nicht sehen. Stellen Sie die Datenbank ohne config.php wieder her, kann sie die Datenbank nicht öffnen. Stellen Sie eine alte Datenbank gegen ein neueres Datenverzeichnis wieder her, zeigen Freigaben auf Dateien, die verschoben wurden.

Sichern Sie alle drei Komponenten von einer in den Wartungsmodus versetzten Instanz:

#!/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/

Der Wartungsmodus sorgt dafür, dass der Dump und die Dateikopie konsistent sind. Überspringen Sie diesen Schritt, erfassen Sie unter Umständen eine Datenbank, die auf eine Datei verweist, die rsync noch nicht erreicht hat. Beachten Sie, dass das Skript datierte Datenbank-Dumps aufbewahrt, aber nur einen rollierenden Spiegel des Datenverzeichnisses erstellt. rsync --delete überschreibt diesen bei jedem Durchlauf, sodass nur der neueste Dump mit der Dateikopie zusammenpasst.

Übertragen Sie die Daten anschließend vom Server. Ein Backup, das auf demselben VPS liegt wie das zu sichernde System, ist lediglich eine Kopie, kein Backup. restic in Richtung Objektspeicher oder auf einen zweiten Host ist die übliche Lösung; dessen Deduplizierung geht mit dem Datenverzeichnis deutlich effizienter um als ein nächtlicher tarball. Die vollständige Einrichtung, von der Repository-Initialisierung über den nächtlichen Timer bis hin zur Wiederherstellungsübung, finden Sie unter Off-Box-VPS-Backups mit restic.

Die Wiederherstellung ist nicht einfach der umgekehrte Vorgang. Ein frisch gestarteter Stack führt den Installer aus und schreibt eine brandneue config.php, eine neue Instanz-ID und ein neues Passwort-Salt. Der Import des Dumps über diese neue Identität führt zu defekten Sitzungen und ungültigen Freigabe-Tokens. Stellen Sie zuerst die alte Identität wieder her, und zwar in dieser Reihenfolge:

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 gleicht den Datei-Cache mit dem tatsächlichen Zustand auf der Festplatte ab. Üben Sie diesen Vorgang einmal auf einem separaten VPS, bevor Sie ihn im Ernstfall benötigen. Die gleiche Trennung zwischen Bytes auf der Festplatte und Metadaten in Postgres gilt für jede andere Anwendung dieser Art. Deshalb führt ein Immich-Backup, das die Bibliothek, aber nicht die Datenbank erfasst, zu einer leeren Zeitleiste.

Upgrades: Immer nur eine Hauptversion

Nextcloud unterstützt Upgrades von exakt einer Hauptversion auf die nächste. Ein Sprung von 29 auf 31 schlägt nicht kontrolliert fehl, sondern endet mit Exception: Updates between multiple major versions and downgrades are unsupported. und versetzt die Instanz in den Wartungsmodus.

Das Docker-Upgrade erfolgt so: Erstellen Sie ein Backup, ändern Sie das Tag in 31 auf 32 in den Diensten app und cron, führen Sie dann docker compose pull && docker compose up -d und anschließend docker compose logs -f app aus. Der Entrypoint des Images erkennt den neueren Code anhand der vorhandenen Daten und führt occ upgrade selbstständig aus. Unterbrechen Sie diesen Vorgang nicht. Sobald die Logs keine Aktivität mehr zeigen, führen Sie docker compose exec -u www-data app php occ status aus und prüfen Sie mit versionstring, ob die Apps wieder aktiviert wurden.

Zwei Regeln bewahren Sie vor Problemen: Erhöhen Sie die Version immer nur um eine Hauptversion, verifizieren Sie den Erfolg und fahren Sie dann mit der nächsten fort. Ändern Sie niemals das Tag des Dienstes app, ohne cron entsprechend anzupassen. Zwei unterschiedliche Nextcloud-Versionen, die auf dieselbe Datenbank zugreifen, führen zu Datenbeschädigungen.

Die Fehler, die Sie tatsächlich sehen werden

"Your data directory is readable by other users. Please change the permissions to 0770." Das per Bind-Mount eingebundene Verzeichnis besitzt Lese-Berechtigungen für die Gruppe oder andere Benutzer. sudo chmod 0770 /srv/nextcloud/data und sudo chown -R 33:33 /srv/nextcloud/data.

"Your data directory is invalid. Ensure there is a file called .ocdata in the root." Der Bind-Mount verweist auf einen Pfad, den Nextcloud nie initialisiert hat, es liegt ein Tippfehler im Pfad vor oder ein leeres Verzeichnis wurde unter einer laufenden Instanz eingebunden. Prüfen Sie, ob der Host-Pfad mit der Volume-Zeile übereinstimmt.

"Access through untrusted domain." Der Hostname in der Anfrage ist nicht in trusted_domains enthalten. NEXTCLOUD_TRUSTED_DOMAINS gilt nur bei der Erstinstallation; danach nehmen Sie die Änderung live vor: occ config:system:set trusted_domains 1 --value=cloud.example.com.

502 Bad Gateway, mit connect() failed (111: Connection refused) while connecting to upstream in /var/log/nginx/error.log. nginx konnte unter 127.0.0.1:8080 keinen Dienst erreichen. Entweder initialisiert der Container noch (prüfen Sie docker compose logs app), er wurde beendet (docker compose ps) oder die Publish-Zeile stimmt nicht mit dem proxy_pass Port überein. Überprüfen Sie dies mit ss -ltnp | grep 8080.

Eine Redirect-Schleife oder "insecure"-Warnungen in der Admin-Übersicht. OVERWRITEPROTOCOL: https fehlt oder TRUSTED_PROXIES enthält nicht das Docker-Gateway-Subnetz. Siehe den Proxy-Abschnitt weiter oben.

LockedException: "files/..." is locked. Wenn REDIS_HOST gesetzt ist, konfiguriert das Image Redis als Locking-Backend und veraltete Locks treten selten auf. Ohne diese Einstellung liegen Locks in der Datenbanktabelle oc_file_locks; eine während des Schreibvorgangs abgebrochene Anfrage hinterlässt dort Zeilen. Stellen Sie sicher, dass Redis tatsächlich verwendet wird; occ config:system:get memcache.locking sollte die Redis-Klasse zurückgeben, bevor Sie Lock-Zeilen manuell löschen.

"The PHP memory limit is below the recommended value of 512MB." Erhöhen Sie PHP_MEMORY_LIMIT und erstellen Sie den Container neu. Bedenken Sie, welche Auswirkungen dies auf den maximalen Speicherbedarf im Worst-Case-Szenario hat.

Was bei Skalierung fehlschlägt

Die erste Hürde ist das Datenverzeichnis, das über das Volume hinauswächst. Die Vergrößerung eines Volumes auf einem VPS erfordert ein Resizing sowie eine Erweiterung des Dateisystems. Dies ist bei einer geplanten Durchführung deutlich weniger problematisch als bei einer Auslastung von 100 %. Richten Sie daher jetzt eine Überwachung der Festplattenbelegung ein, nicht erst später.

Die zweite Hürde ist oc_filecache. Dateiauflistungen und Synchronisations-Scans verlangsamen sich mit steigender Zeilenanzahl. Die Lösung liegt in der Datenbankoptimierung: Betreiben Sie Postgres auf schnellem Speicher, stellen Sie ausreichend Shared Memory bereit und bereinigen Sie veraltete Daten sowie Versionen über Aufbewahrungsrichtlinien, anstatt sie unbegrenzt ansammeln zu lassen.

Die dritte Hürde ist die Vorschau-Generierung, die mit allen anderen Prozessen konkurriert. Beschränken Sie auf kleinen Systemen die Vorschau-Anbieter und führen Sie occ preview:generate-all niemals während der Arbeitszeit aus. Wenn der Großteil Ihrer Daten aus Fotos von Mobiltelefonen besteht, sollte die Erstellung der Vorschaubilder auf einen dedizierten Fotoserver ausgelagert werden. Vergleich von PhotoPrism und Immich hinsichtlich RAM, Smartphone-Apps und Backup-Befehlen erläutert die Anforderungen dieser Lösungen im Vergleich zu einer Nextcloud-Instanz.

Darüber hinaus ist die ehrliche Antwort, dass Zusatzdienste eigene Maschinen benötigen. Collabora und die Volltextsuche sind eigenständige, speicherintensive Dienste. Sie auf dem Server zu betreiben, der gleichzeitig Ihre einzige Dateikopie enthält, vergrößert den Fehlerbereich ohne nennenswerten Vorteil. Wenn Sie Dokumente im Browser bearbeiten möchten, entscheiden die vom Anbieter vorgegebenen RAM-Mindestanforderungen und Verbindungslimits, die OnlyOffice von Collabora unterscheiden, welche Lösung auf einem VPS mit 2 bis 4 GB RAM überhaupt betrieben werden kann. Lagern Sie die Dateispeicherung auf S3-kompatiblen Speicher aus, sobald das Volume nicht mehr ausreicht. Beachten Sie dabei, dass dies Backups erschwert, nicht vereinfacht: Die Datenbank enthält weiterhin die Metadaten und muss synchron mit dem Bucket gesichert werden.

Sobald die Instanz von echten Benutzern verwendet wird, schalten Sie Uptime Kuma davor, damit Sie von Ausfallzeiten erfahren, bevor die Sync-Clients dies tun. Eine Private Cloud lässt sich gut mit einem eigenen Mailserver kombinieren. Wenn Sie Dienste nicht manuell miteinander verknüpfen möchten, vergleichen Cloudron, CasaOS und Coolify die Plattformen, die dies für Sie übernehmen. Falls als Nächstes eine selbst gehostete Suchmaschine geplant ist, erwarten Sie eine andere Art von Problemen als die oben genannten: Die 429-Fehler von SearXNG resultieren entweder aus dem eigenen Rate-Limiter oder daraus, dass die Upstream-Suchmaschinen Ihre VPS-IP blockieren. Nur das Logfile verrät Ihnen, welche Ursache vorliegt.

FAQ

Kann ich Nextcloud mit SQLite anstelle von Postgres betreiben?

Das ist möglich und das offizielle Image erlaubt dies, aber ein einzelner Desktop-Sync-Client, der parallele Anfragen sendet, wird auf SQLSTATE[HY000]: General error: 5 database is locked stoßen und HTTP 500-Fehler verursachen. SQLite setzt eine datenbankweite Schreibsperre, während Nextcloud ständig schreibt: Dateisperren, Aktivitätszeilen und Job-Status. Beginnen Sie direkt mit Postgres oder MariaDB; occ db:convert-type existiert zwar, ist aber eine langwierige Alles-oder-Nichts-Migration auf Live-Daten.

Wie viel RAM benötigt ein Nextcloud-VPS tatsächlich?

Planen Sie für die Gleichzeitigkeit, nicht für die Benutzeranzahl. Der Worst-Case für den residenten Speicher entspricht in etwa der Anzahl gleichzeitiger Anfragen multipliziert mit PHP_MEMORY_LIMIT, zuzüglich der Postgres Shared Buffers und eines Backends pro Verbindung, sowie der Lastspitzen bei der Vorschaubild-Generierung. Ein 2 GB-Server reicht für eine kleine Instanz im Haushalt, wenn Sie die Vorschauen begrenzen und Swap hinzufügen; fügen Sie Collabora oder eine Volltextsuche hinzu, müssen Sie ein zweites Set an residenten Diensten einplanen.

Warum schlagen große Uploads hinter dem nginx-Reverse-Proxy fehl?

Zwei Einstellungen am Proxy sind meist die Ursache: client_max_body_size, das auf dem Standardwert von 1 MB belassen wurde, bricht die Anfrage ab, und zu kurze proxy_read_timeout- / proxy_send_timeout-Werte beenden lange Übertragungen vorzeitig. Setzen Sie beide Werte großzügig, stellen Sie proxy_request_buffering off auf Streaming statt Spooling um und erhöhen Sie PHP_UPLOAD_LIMIT im App-Container entsprechend.

Warum leitet Nextcloud in einer Endlosschleife um oder warnt vor dem Reverse-Proxy?

Der Container sieht nginx nicht unter 127.0.0.1, sondern das Docker-Bridge-Gateway, das sich in 172.x befindet. Wenn diese Adresse in TRUSTED_PROXIES fehlt, wird der X-Forwarded-Proto: https-Header ignoriert, Nextcloud generiert http://-URLs und der Proxy leitet diese zurück. Setzen Sie TRUSTED_PROXIES auf das tatsächliche Bridge-Subnetz und fixieren Sie OVERWRITEPROTOCOL: https.

Kann ich Nextcloud direkt von 29 auf 31 aktualisieren?

Nein. Nextcloud unterstützt nur eine Hauptversion pro Upgrade; das Überspringen führt zu Updates between multiple major versions and downgrades are unsupported. und belässt die Instanz im Wartungsmodus. Erstellen Sie ein Backup, erhöhen Sie das Tag um eine Hauptversion bei den Diensten app und cron, führen Sie docker compose pull && docker compose up -d aus, prüfen Sie dies mit occ status und wiederholen Sie den Vorgang.