Zum Inhalt

Nextcloud Hub Self-Hosting: Produktionsarchitektur & Härtung

Erstellt: 05.11.2026  ·  Zuletzt aktualisiert: 06.11.2026  ·  Nejat Hakan

Offizielles Nextcloud-Logo

Nextcloud Hub ist die führende Open-Source-Plattform für sichere Content-Kollaboration. Während kommerzielle SaaS-Clouds (Google Workspace, Microsoft 365, Dropbox) private Dokumente, Kalender und Kommunikationsdaten auf fremder Infrastruktur speichern, verbleiben beim Self-Hosting von Nextcloud 100 % deiner Daten, Verschlüsselungsschlüssel und Zugriffsprotokolle unter deiner vollen Kontrolle.

Dieser Leitfaden geht weit über einfache Test-Installationen hinaus: Wir konzipieren einen produktionsreifen, gehärteten Nextcloud-Stack mit transaktionalem Redis File Locking, APCu/OPcache-Beschleunigung, automatisierten Hintergrund-Cron-Containern, TLS-Reverse-Proxying und atomaren Backup-Pipelines.


1. Nextcloud Hub Ökosystem & Referenzarchitektur

Nextcloud ist weit mehr als ein einfacher Datei-Sync-Dienst. Das modulare Ökosystem ersetzt eine Vielzahl proprietärer Cloud-Dienste:

  • Nextcloud Files


    Dateisynchronisation für Unternehmen, granulare Freigaben mit Passwort- und Ablaufrichtlinien, Dateiversionierung, serverseitige Verschlüsselung und Einbindung externer S3-/SMB-Speicher.

  • Nextcloud Groupware


    Natives CalDAV (Kalender), CardDAV (Kontakte), Kanban-Boards (Deck), Markdown-Notes und ein integrierter Webmail-Client mit nahtlosem Sync zu iOS, Android und Thunderbird.

  • Nextcloud Office (WOPI)


    Gemeinsame Echtzeitbearbeitung von .docx-, .xlsx-, .pptx- und .odt-Dokumenten direkt im Browser über Collabora Online (CODE) oder ONLYOFFICE Docs.

  • Nextcloud Talk


    Ende-zu-Ende-verschlüsselte WebRTC-Audio-/Videokonferenzen, Screen-Sharing und Team-Chat – erweiterbar um dedizierte STUN/TURN (coturn)-Server und High-Performance-Backends.

Produktions-Referenzarchitektur

Eine träge Nextcloud-Instanz ist fast immer die Folge fehlender Caching-Ebenen oder der Nutzung von SQLite/AJAX statt einer dedizierten Datenbank, Redis und System-Cron. Unser Referenz-Stack trennt die Aufgaben auf vier isolierte Tiers:

%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
    Client["🌐 Web-, Desktop- & Mobile-Clients"]
    Proxy["🔒 Edge Reverse-Proxy (Nginx / Caddy / Traefik)<br/>TLS 1.3 · HSTS · CalDAV / CardDAV-Redirects"]

    subgraph AppCluster ["⚙️ Nextcloud Applikations-Ebene (Docker Compose)"]
        NC["🔵 Nextcloud Core App<br/>(PHP 8.3 + OPcache + APCu)"]
        Cron["⏱️ Cron-Sidecar Worker<br/>(Führt cron.php alle 5 Min. aus)"]
    end

    subgraph DataCluster ["💾 Persistenz & State-Services"]
        Redis[("⚡ Redis In-Memory Store<br/>Transaktionales File-Locking")]
        DB[("🐘 PostgreSQL / MariaDB<br/>Metadaten, User & Shares")]
        Storage["📁 NVMe Host-Volumes<br/>/var/www/html & /data"]
    end

    Client ==>|"HTTPS :443"| Proxy
    Proxy ==>|"HTTP :8080"| AppCluster
    AppCluster -->|"TCP :6379 Locks"| Redis
    AppCluster -->|"TCP :5432 SQL"| DB
    AppCluster -->|"Dateisystem I/O"| Storage

2. Bereitstellung des Produktions-Stacks (Docker Compose)

Statt eines unvollständigen Setups setzen wir von Anfang an auf die vollständige 4-Container-Produktionseinheit (app, cron, db, redis).

Warum ein dedizierter cron-Sidecar-Container?

Durch das Ausführen eines zweiten schlanken Containers mit demselben nextcloud-Image und überschriebenem Entrypoint auf /cron.sh laufen Hintergrundaufgaben verlässlich alle 5 Minuten, ohne die /etc/crontab deines Host-Servers zu belasten!

Schritt 1: Projektverzeichnis & Umgebungsvariablen anlegen

Passwörter für Datenbank und Redis gehören niemals im Klartext in die docker-compose.yml. Wir legen sie in einer restriktiven .env-Datei ab (chmod 600):

Terminal: Verzeichnisstruktur & geschützte .env-Datei anlegen
mkdir -p ~/nextcloud-stack && cd ~/nextcloud-stack

cat << 'EOF' > .env
# --- Datenbank-Zugangsdaten ---
POSTGRES_DB=nextcloud
POSTGRES_USER=nextcloud
POSTGRES_PASSWORD=ChangeMe_SuperSecret_DB_Pass_2026!

MYSQL_ROOT_PASSWORD=ChangeMe_SuperSecret_Root_Pass_2026!
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
MYSQL_PASSWORD=ChangeMe_SuperSecret_DB_Pass_2026!

# --- Redis-Zugangsdaten ---
REDIS_HOST_PASSWORD=ChangeMe_SuperSecret_Redis_Pass_2026!

# --- Nextcloud Domain & Performance-Tuning ---
NEXTCLOUD_TRUSTED_DOMAINS=cloud.example.com localhost
OVERWRITEPROTOCOL=https
OVERWRITEHOST=cloud.example.com
PHP_MEMORY_LIMIT=1024M
PHP_UPLOAD_LIMIT=16G
EOF

chmod 600 .env

Schritt 2: Datenbank-Stack wählen (docker-compose.yml)

Wähle entweder PostgreSQL 16 (empfohlen für maximale Nebenläufigkeit und geringe Latenz) oder MariaDB 11 LTS (klassischer LAMP-Standard mit READ-COMMITTED-Transaktionsisolation):

~/nextcloud-stack/docker-compose.yml
services:
  db:
    image: docker.io/library/postgres:16-alpine
    container_name: nextcloud-db
    restart: unless-stopped
    volumes:
      - nextcloud_db:/var/lib/postgresql/data
    env_file:
      - .env
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: docker.io/library/redis:7-alpine
    container_name: nextcloud-redis
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_HOST_PASSWORD} --save 60 1 --loglevel warning
    volumes:
      - nextcloud_redis:/data

  app:
    image: docker.io/library/nextcloud:stable-apache
    container_name: nextcloud-app
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_data:/var/www/html/data
    env_file:
      - .env
    environment:
      - POSTGRES_HOST=db
      - REDIS_HOST=redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  cron:
    image: docker.io/library/nextcloud:stable-apache
    container_name: nextcloud-cron
    restart: unless-stopped
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_data:/var/www/html/data
    entrypoint: /cron.sh
    depends_on:
      - app

volumes:
  nextcloud_db:
  nextcloud_redis:
  nextcloud_html:
  nextcloud_data:
~/nextcloud-stack/docker-compose.yml
services:
  db:
    image: docker.io/library/mariadb:11.4
    container_name: nextcloud-db
    restart: unless-stopped
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW --innodb-file-per-table=1
    volumes:
      - nextcloud_db:/var/lib/mysql
    env_file:
      - .env
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: docker.io/library/redis:7-alpine
    container_name: nextcloud-redis
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_HOST_PASSWORD} --save 60 1 --loglevel warning
    volumes:
      - nextcloud_redis:/data

  app:
    image: docker.io/library/nextcloud:stable-apache
    container_name: nextcloud-app
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_data:/var/www/html/data
    env_file:
      - .env
    environment:
      - MYSQL_HOST=db
      - REDIS_HOST=redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  cron:
    image: docker.io/library/nextcloud:stable-apache
    container_name: nextcloud-cron
    restart: unless-stopped
    volumes:
      - nextcloud_html:/var/www/html
      - nextcloud_data:/var/www/html/data
    entrypoint: /cron.sh
    depends_on:
      - app

volumes:
  nextcloud_db:
  nextcloud_redis:
  nextcloud_html:
  nextcloud_data:

Schritt 3: Stack starten und überprüfen

Terminal: Stack starten & Container-Zustand prüfen
docker compose up -d
docker compose ps

3. Reverse Proxy, TLS & Sicherheits-Härtung

Unser app-Container bindet strikt an 127.0.0.1:8080:80. Er wird niemals unverschlüsselt direkt ins Internet exponiert. Ein Host-Reverse-Proxy (Nginx oder Caddy) terminiert TLS 1.3, erzwingt HSTS und verarbeitet die obligatorischen CalDAV-/CardDAV-Weiterleitungen (/.well-known/).

/etc/nginx/sites-available/nextcloud.conf
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name cloud.example.com;

    # SSL-Zertifikate (z. B. via Certbot / Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/cloud.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cloud.example.com/privkey.pem;

    # Strict Transport Security (HSTS) - Notwendig für Nextcloud-Sicherheitsprüfung!
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # Große Uploads erlauben (passend zu PHP_UPLOAD_LIMIT)
    client_max_body_size 16G;
    fastcgi_buffers 64 4K;

    # Obligatorische CalDAV- & CardDAV-Service-Discovery-Redirects
    location = /.well-known/carddav { return 301 https://$host/remote.php/dav/; }
    location = /.well-known/caldav  { return 301 https://$host/remote.php/dav/; }

    location / {
        proxy_pass http://127.0.0.1:8080;
        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_buffering off;
        proxy_request_buffering off;
    }
}
/etc/caddy/Caddyfile
cloud.example.com {
    header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

    redir /.well-known/carddav /remote.php/dav/ 301
    redir /.well-known/caldav /remote.php/dav/ 301

    reverse_proxy 127.0.0.1:8080
}

Härtung nach der Installation via occ (Warnungen eliminieren)

Nach Abschluss des Web-Installers unter https://cloud.example.com führst du diesen automatisierten occ-Block aus, um Trusted Proxies, Standard-Telefonregionen, Wartungsfenster und fehlende Datenbank-Indizes zu setzen:

Hands-On Lab 1: A+-Sicherheitsbewertung via occ erreichen

Führe diese Befehle im Projektverzeichnis aus, um alle Warnungen unter Verwaltungseinstellungen → Übersicht zu bereinigen:

Terminal: Trusted Proxies, Caching & DB-Optimierung konfigurieren
# 1. Hintergrundaufgaben offiziell auf System-Cron umstellen
docker compose exec -u www-data app php occ background:cron

# 2. Standard-Telefonregion setzen (ISO-3166-1-Code, z. B. DE für Deutschland)
docker compose exec -u www-data app php occ config:system:set default_phone_region --value="DE"

# 3. Nächtliches Wartungsfenster definieren (z. B. 02:00 Uhr UTC)
docker compose exec -u www-data app php occ config:system:set maintenance_window_start --type=integer --value=2

# 4. Lokalen Reverse-Proxy als vertrauenswürdig einstufen & HTTPS-URL erzwingen
docker compose exec -u www-data app php occ config:system:set trusted_proxies 0 --value="127.0.0.1"
docker compose exec -u www-data app php occ config:system:set trusted_proxies 1 --value="172.16.0.0/12"
docker compose exec -u www-data app php occ config:system:set overwrite.cli.url --value="https://cloud.example.com"

# 5. Fehlende Datenbank-Indizes ergänzen & Filecache-Spalten auf BigInt konvertieren
docker compose exec -u www-data app php occ db:add-missing-indices
docker compose exec -u www-data app php occ db:convert-filecache-bigint --no-interaction

Zwei-Faktor-Authentifizierung (2FA) erzwingen

Passwörter allein reichen für eine öffentlich erreichbare Cloud nicht aus. Nextcloud unterstützt sowohl TOTP (Aegis, Ente Auth, Google Authenticator) als auch phishing-resistente WebAuthn / FIDO2-Hardware-Schlüssel (YubiKey, Passkeys):

Terminal: TOTP-2FA via CLI installieren & aktivieren
# 1. Offizielle TOTP-App herunterladen und aktivieren
docker compose exec -u www-data app php occ app:install twofactor_totp
docker compose exec -u www-data app php occ app:enable twofactor_totp

# 2. 2FA-Status für einen Benutzer prüfen
docker compose exec -u www-data app php occ twofactorauth:state admin

2FA-Backup-Codes immer sicher aufbewahren!

Speichere beim Aktivieren von TOTP unter Persönliche Einstellungen → Sicherheit sofort die 10 Einmal-Backup-Codes im Passwortmanager (z. B. KeePassXC oder Vaultwarden). Solltest du dein Smartphone verlieren, kannst du als Server-Administrator ein gesperrtes Konto auch über die CLI entsperren:

docker compose exec -u www-data app php occ twofactorauth:disable <username> totp


4. Performance-Tuning: OPcache, APCu & Redis Locking

Ohne Caching löst jeder Datei-Upload oder WebDAV-Sync dutzende PHP-Skripte und Sperrabfragen in der SQL-Datenbank aus. Bei 1.000 kleinen Dateien bricht die Datenbank ein und meldet HTTP 423 Locked.

Das 3-Stufen-Caching-Modell

%%{init: {'flowchart': {'wrappingWidth': 600}}}%%
flowchart TB
    Req(("⚡ Eingehender<br/>WebDAV-Request")) --> OP["1️⃣ PHP OPcache<br/>(Bytecode im RAM)"]
    OP --> APCu["2️⃣ APCu (memcache.local)<br/>(Lokaler Shared Memory)"]
    APCu --> Redis["3️⃣ Redis (memcache.locking)<br/>(Atomare File-Locks & Cache)"]
    Redis --> DB[("4️⃣ PostgreSQL / MariaDB<br/>(Nur bei Cache-Miss angefragt)")]
Cache-Schicht Konfigurationsschlüssel in config.php Funktion & Auswirkung
PHP OPcache opcache.enable=1 Hält kompilierten PHP-Bytecode im RAM, damit Skripte nicht bei jedem Request neu geparst werden.
APCu (L1-Cache) 'memcache.local' => '\OC\Memcache\APCu' Schnellster lokaler Shared-Memory-Speicher für Konfigurations- und Übersetzungs-Lookups.
Redis (L2-Cache) 'memcache.distributed' => '\OC\Memcache\Redis' Geteilter Cache über Worker-Prozesse und cron-Sidecar-Container hinweg.
Redis File Locking 'memcache.locking' => '\OC\Memcache\Redis' Zentral: Ersetzt langsame SQL-Tabellensperren durch transaktionale Sperren im Arbeitsspeicher im Sub-Millisekunden-Bereich.

Hands-On Lab 2: Aktiven Status von APCu & Redis verifizieren

In unserem docker-compose.yml sorgt REDIS_HOST=redis für die automatische Konfiguration. Prüfe, ob beide Mechanismen in config/config.php aktiv sind und der OPcache ausreichend bemessen ist:

Terminal: Aktive Cache-Konfiguration & OPcache-Status prüfen
# 1. memcache.local, memcache.distributed und memcache.locking in config.php überprüfen
docker compose exec -u www-data app grep -E "memcache|redis" -A 5 config/config.php

# 2. PHP OPcache Speicherlimit und JIT/Puffer überprüfen
docker compose exec app php -i | grep -E "opcache.enable |opcache.memory_consumption|opcache.interned_strings_buffer|opcache.max_accelerated_files"

5. Office-Integration (WOPI), Externer Speicher & Talk

Collabora Online vs. ONLYOFFICE Docs

Zur gemeinsamen Bearbeitung von .docx-, .xlsx- und .pptx-Dateien im Browser integriert Nextcloud über das WOPI-Protokoll zwei Office-Lösungen:

Basiert auf LibreOffice. Rendert Dokumente serverseitig und streamt Bildkacheln an den Browser – sensible Inhalte verlassen den Server nicht und laufen auch auf schwachen Endgeräten performant.

Zu docker-compose.yml hinzufügen: Collabora Online Server
  collabora:
    image: docker.io/collabora/code:latest
    container_name: nextcloud-collabora
    restart: unless-stopped
    ports:
      - "127.0.0.1:9980:9980"
    environment:
      - domain=cloud\\.example\\.com
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true
Nextcloud-Connector-App aktivieren:
docker compose exec -u www-data app php occ app:install richdocuments

Rendert Dokumente direkt im Client-Browser via HTML5-Canvas für maximale Microsoft-Office-Kompatibilität. Sicherheitsregel: Niemals mit JWT_ENABLED=false betreiben – immer ein gemeinsames JWT_SECRET erzwingen, um unbefugte Nutzung zu verhindern!

Zu docker-compose.yml hinzufügen: ONLYOFFICE mit verbindlicher JWT-Authentifizierung
  onlyoffice:
    image: docker.io/onlyoffice/documentserver:latest
    container_name: nextcloud-onlyoffice
    restart: unless-stopped
    ports:
      - "127.0.0.1:8082:80"
    environment:
      - JWT_ENABLED=true
      - JWT_SECRET=ChangeMe_UltraStrong_JWT_Secret_Key_2026!
      - JWT_HEADER=Authorization
    volumes:
      - onlyoffice_data:/var/www/onlyoffice/Data
      - onlyoffice_log:/var/log/onlyoffice
Nextcloud-Connector-App aktivieren:
docker compose exec -u www-data app php occ app:install onlyoffice


6. Atomare Datensicherung & Disaster-Recovery-Pipeline

Ein verlässliches Nextcloud-Backup besteht aus drei untrennbaren Komponenten: 1. Die Konfiguration (config/config.php): Enthält die kryptografische instanceid, passwordsalt und secret. (Ohne secret und passwordsalt werden verschlüsselte Passwörter und 2FA-Secrets in der Datenbank dauerhaft unlesbar!) 2. Der Datenbank-Dump (.sql): Speichert Benutzer, Ordnerstrukturen, Datei-IDs, Freigaben, Kalender und Kontakte. 3. Das Datenverzeichnis (data/): Beinhaltet die eigentlichen Benutzerdateien.

Der atomare Backup-Ablauf

Um Race Conditions zu verhindern (Dateiupload während des DB-Dumps, was den Index korrumpiert), muss jedes Backup Datenbank-Dump und Dateisynchronisation zwingend im maintenance:mode kapseln:

%%{init: {'flowchart': {'wrappingWidth': 600}}}%%
flowchart TB
    Step1["🔒 1. Wartungsmodus AN<br/>(occ maintenance:mode --on)"] ==> Step2["🗄️ 2. Konsistenter DB-Dump<br/>(pg_dump / mysqldump)"]
    Step2 ==> Step3["💾 3. Daten & Config sichern<br/>(rsync / Borg / Restic)"]
    Step3 ==> Step4["🟢 4. Wartungsmodus AUS<br/>(occ maintenance:mode --off)"]

Hands-On Lab 3: Automatisiertes Produktions-Backup-Skript

Dieses Skript nutzt einen Bash-trap: Selbst wenn das Skript abbricht oder mit Strg+C beendet wird, schaltet es den Wartungsmodus garantiert automatisch wieder ab!

~/scripts/backup_nextcloud.sh
#!/usr/bin/env bash
set -euo pipefail

COMPOSE_DIR="$HOME/nextcloud-stack"
BACKUP_ROOT="/mnt/backups/nextcloud"
RETENTION_DAYS=14
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
DEST_DIR="${BACKUP_ROOT}/${TIMESTAMP}"

mkdir -p "${DEST_DIR}"
cd "${COMPOSE_DIR}"

# Sicherheits-Trap: Wartungsmodus bei Skriptende immer zuverlässig deaktivieren!
cleanup() {
    echo "[INFO] Schalte Nextcloud-Wartungsmodus ab..."
    docker compose exec -T -u www-data app php occ maintenance:mode --off || true
}
trap cleanup EXIT

echo "[1/4] Aktiviere Nextcloud-Wartungsmodus..."
docker compose exec -T -u www-data app php occ maintenance:mode --on

echo "[2/4] Erstelle konsistenten Datenbank-Dump..."
# Für PostgreSQL (bei MariaDB: mysqldump --single-transaction anpassen):
docker compose exec -T -u postgres db sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB"' | gzip > "${DEST_DIR}/nextcloud_db.sql.gz"

echo "[3/4] Sichere Nextcloud-Konfiguration & Daten-Volumes..."
HTML_VOL="$(docker volume inspect -f '{{.Mountpoint}}' nextcloud-stack_nextcloud_html)"
DATA_VOL="$(docker volume inspect -f '{{.Mountpoint}}' nextcloud-stack_nextcloud_data)"

sudo rsync -a --delete "${HTML_VOL}/config/" "${DEST_DIR}/config/"
sudo rsync -a --delete "${DATA_VOL}/" "${DEST_DIR}/data/"

echo "[4/4] Bereinige Backups älter als ${RETENTION_DAYS} Tage..."
find "${BACKUP_ROOT}" -maxdepth 1 -mindepth 1 -type d -mtime +"${RETENTION_DAYS}" -exec rm -rf {} +

echo "[OK] Backup erfolgreich abgeschlossen unter: ${DEST_DIR}"

7. Skalierung & Hochverfügbarkeit (HA)

Bei der Skalierung über einen einzelnen Server hinaus (mehrere hundert aktive Benutzer) wandelt sich die Architektur zu einer zustandslosen Anwendungsschicht:

%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
    LB["⚖️ HAProxy / Traefik Load Balancer<br/>Round-Robin & Health Checks"]

    subgraph Cluster ["⚙️ Zustandsloser Nextcloud App-Pool (PHP-FPM)"]
        direction LR
        N1["🔵 Node 1"]
        N2["🔵 Node 2"]
        N3["🔵 Node 3"]
    end

    subgraph Services ["🗄️ Geteilte Enterprise-Infrastruktur"]
        RedisC[("⚡ Redis Sentinel Cluster<br/>Zentrales Session- & Lock-Management")]
        DBC[("🐘 PostgreSQL Patroni / Galera<br/>Synchron replizierte Datenbank")]
        StorageC[("💾 S3 Objektspeicher / CephFS<br/>Zentraler Datei- & Objektspeicher")]
    end

    LB ==>|"HTTP-Traffic verteilt"| Cluster
    Cluster -->|"Sessions & Dateisperren"| RedisC
    Cluster -->|"SQL-Transaktionen"| DBC
    Cluster -->|"S3 API / Dateizugriff"| StorageC
  1. Geteilte Sessions & Locks: Alle zustandslosen PHP-FPM-Knoten speichern Sessions (session.save_handler = redis) und Dateisperren (memcache.locking) in einem gemeinsamen Redis-Sentinel-Cluster.
  2. S3 als Primärspeicher: Statt netzwerkbasierter Dateisysteme (NFS) binden Enterprise-Setups S3-kompatiblen Objektspeicher (MinIO / Ceph RGW) direkt als primären Speicher ein (objectstore in config.php).
  3. Notify Push (notify_push): Ersetzt permanentes Polling durch einen schlanken Rust-Daemon, der Dateiänderungen in Echtzeit via WebSockets an Clients pusht – das reduziert die Request-Last um bis zu 80 %.

8. Fehlerbehebung & CLI-Notfallhilfe

1. Dateien können nicht gelöscht oder hochgeladen werden (HTTP 423 Locked)

Ursache: Eine Synchronisation wurde unterbrochen, während eine Sperre aktiv war, oder Redis File Locking ist nicht konfiguriert.

Lösung: Prüfe, ob Redis für 'memcache.locking' => '\OC\Memcache\Redis' aktiv ist, und führe eine Reparatur durch:

docker compose exec -u www-data app php occ maintenance:mode --on
docker compose exec -u www-data app php occ maintenance:repair
docker compose exec -u www-data app php occ maintenance:mode --off

2. Direkt auf die Festplatte kopierte Dateien erscheinen nicht im Web-Interface

Ursache: Nextcloud verwaltet alle Dateien in der internen Datenbank (oc_filecache). Werden Dateien direkt im data/-Verzeichnis verändert, fehlt der Datenbank-Eintrag.

Lösung: Dateisystem-Neuscan anstoßen:

docker compose exec -u www-data app php occ files:scan --all

3. 'Zugriff über eine nicht vertrauenswürdige Domain' nach Domain-/IP-Änderung

Ursache: Nextcloud blockiert HTTP-Host-Header, die nicht im Array trusted_domains in config/config.php stehen.

Lösung: Neue Domain via occ hinzufügen:

docker compose exec -u www-data app php occ config:system:set trusted_domains 2 --value="cloud.meinedomain.de"

4. Desktop-Client meldet sich ständig ab oder verharrt in Login-Schleife

Ursache: Nextcloud empfängt reines HTTP vom lokalen Reverse-Proxy (127.0.0.1:8080) und generiert http://-URLs statt https://.

Lösung: overwriteprotocol in config/config.php erzwingen:

docker compose exec -u www-data app php occ config:system:set overwriteprotocol --value="https"