Compose und stack-relevante Config ohne Volumes/Daten; Secrets REDACTED. Co-authored-by: Cursor <cursoragent@cursor.com>
14 KiB
VM 101 (ubuntu) — Nextcloud Status & Optimierung
Stand: 2026-06-28
Host: pve1 · VMID: 101 · IP: 192.168.10.10
URL: https://cloud.jeanavril.com
Diese Seite dokumentiert den Ist-Zustand nach dem CPU-Incident am 28.06.2026 und sammelt Optimierungsoptionen zur eigenen Recherche. Client-Updates sind hilfreich, aber nicht Voraussetzung für eine stabile Server-Seite.
Architektur (Kurz)
pve1 (192.168.10.5)
└── VM 101 ubuntu (4 vCPU, **12 GB RAM**, 192.168.10.10)
├── Docker: nextcloud → 10.2.2.253 (docbr0)
├── Docker: nextcloud-db-1 (MariaDB)
├── Docker: nextcloud-redis-1 (Redis Alpine)
├── Docker: collabora
├── Docker: npm-app-1 → Reverse Proxy 10.2.2.254
└── … weitere Stacks (Gitea, Airsonic, Vaultwarden, …)
Daten:
/mnt/nextcloud-data ← NFS von pve1/CT files
192.168.10.5:/mnt/storage/service_data/cloud/data (mergerfs-Pool, ~99 TB, ~95 % belegt)
im Container: /data
Stack-Pfad auf der VM: /opt/stacks/nextcloud/
Compose (Repo): [guests/vm101-ubuntu/stacks/nextcloud/](../guests/vm101-ubuntu/stacks/nextcloud/)
Compose (Live): /opt/stacks/nextcloud/compose.yml
Nextcloud-Config: /opt/stacks/nextcloud/config/www/nextcloud/config/config.php
Image: lscr.io/linuxserver/nextcloud:latest (NC 34.0.0.12 = Hub 26 Spring)
Versionsstand (verifiziert 2026-06-28): NC 34.0.0 — das ist die neueste Major-Version (Hub 26 Spring). Die ADA Engine ist bereits aktiv (seit NC 33). Es gibt kein anstehendes „Hub-26-Upgrade“ — nur Minor-Patches (z. B. 34.0.1) und Betriebs-Tuning.
Schritt-für-Schritt-Anleitung: ../migration/nextcloud-optimierung-und-updates.md
Incident 2026-06-28 (CPU 100 %)
Symptome
| Ebene | Beobachtung |
|---|---|
| Proxmox-Host | KVM VM 101 ~400 % CPU, Load ~4 |
| In der VM | Load ~17 bei 4 Kernen |
Container nextcloud |
~398 % CPU |
| PHP-FPM | 5/5 Worker (pm.max_children = 5) seit 2–5 Stunden bei 100 % CPU |
| Nginx | massenhaft 504 Gateway Timeout an Clients |
| Clients | Desktop (mirall) + Android pollten index.php/204, status.php, WebDAV-PROPFIND |
Sofortmaßnahme (erledigt)
# auf pve1 oder per Guest Agent:
qm guest exec 101 -- docker restart nextcloud
→ CPU sofort normal (~0 %), frische PHP-FPM-Prozesse.
Wahrscheinliche Ursache (Server-seitig)
Die Worker hingen im OCS/WebDAV-Pfad (cwd: /app/www/public/ocs), nicht in MariaDB oder Redis. Kombination aus:
- Zu wenig PHP-FPM-Slots (5) — bei parallelen Sync-/WebDAV-Requests sofort erschöpft
- Kein Push-Backend — Clients müssen aktiv pollen statt Updates zu empfangen
- Sehr großer NFS-Datenbestand (~93 TB) — Metadaten-/Scan-Operationen können PHP-Worker lange binden
- Kein Request-Timeout auf PHP-FPM-Ebene sichtbar — Worker können theoretisch unbegrenzt laufen
Client-Versionen (z. B. altes mirall 3.0.3) verstärken die Last durch häufigeres Polling, sind aber nicht die alleinige Ursache.
Ist-Zustand Konfiguration
Bereits korrekt / aktiv
| Bereich | Status | Details |
|---|---|---|
| Redis (Distributed Cache) | ✅ | memcache.distributed + memcache.locking → Redis |
| APCu (Local Cache) | ✅ | memcache.local → APCu |
| Transactional File Locking | ✅ | filelocking.enabled = true, Locking via Redis |
| PHP-Module | ✅ | redis, apcu, Zend OPcache geladen |
| OPcache | ✅ | enabled, 128 MB |
| Datenbank | ✅ | MariaDB im Compose-Stack (db Host) |
| Reverse Proxy | ✅ | NPM (10.2.2.254), trusted_proxies gesetzt |
→ Der Linuxserver-Container-Hinweis beim Start („Redis konfigurieren …“) ist veraltet/irreführend — Redis ist in config.php eingetragen.
Engpässe / fehlend
| Bereich | Status | Auswirkung |
|---|---|---|
PHP-FPM pm.max_children |
✅ 12 (seit 2026-06-28) | www2.conf + Container-Recreate |
APCu apc.shm_size |
✅ 128M | php-local.ini |
| Background-Jobs | ✅ System-Cron (5 min) | root-crontab |
| VM RAM | ✅ 12 GB | qm set 101 -memory 12288 |
| Separates Redis für notify_push | ❌ | Optional, erst relevant mit HPB |
notify_push (Rust HPB) |
✅ v1.3.3 + Sidecar nextcloud-notify-push |
Setup OK 2026-06-28; Polling-Reduktion beobachten |
| Preview-/Scan-Jobs | ❓ ungeprüft | Bei 93 TB NFS potenziell sehr teuer |
PHP-FPM (Container-Default)
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
Anpassbar über Linuxserver-Pfad (persistent):
/opt/stacks/nextcloud/config/php/www2.conf → gemountet nach /etc/php84/php-fpm.d/www.conf
(Die genaue php-Version im Container bei Image-Update prüfen.)
Rust „Engine“ — was ist das?
Es gibt zwei verschiedene Rust-Themen; oft verwechselt:
1. notify_push — High Performance Backend für Files (jetzt umsetzbar)
| Was | Rust-Daemon + Nextcloud-App, hält WebSocket-Verbindungen zu Desktop-/Web-Clients offen |
| Problem das es löst | Clients fragen sonst alle paar Sekunden index.php/204 / status.php ab → PHP-FPM-Last |
| Repo | https://github.com/nextcloud/notify_push |
| Lizenz | AGPL, kostenlos (nicht Enterprise-only) |
| Aktuell | App installiert (v1.3.3), Sidecar auf Port 7867 |
| Voraussetzungen | Redis (✅ vorhanden), Reverse-Proxy-Weiterleitung für Push-Port, passende Binary-Version zur App |
Relevanz für uns: Sehr hoch — adressiert direkt das Polling-Problem (index.php/204, status.php), unabhängig von Client-Version.
Konfiguration laut Doku:
- App installieren + Rust-Binary (
notify_push-x86_64-unknown-linux-musl) als Sidecar oder im Container - Proxy-Pfad z. B.
/push→ Push-Daemon - Optional: separates Redis (
notify_push_redisin config.php) für Pub/Sub-Traffic
Aktuelle Releases: v1.3.x (2026), u. a. Fixes gegen DB-Query-Spitzen bei Cache-Invalidierung.
2. ADA Engine — Accelerated Direct Access (bereits in NC 33/34)
| Was | Architektur-Rewrite für Skalierung (File-Cache, Mounts, Previews, Push an Clients) |
| Debüt | NC 33 = Hub 26 Winter (Feb 2026) |
| Bei uns | NC 34.0.0 — ADA bereits enthalten |
| S3-Direct-Download | Greift nicht bei NFS-Daten (nur S3-Storage) |
| HPB Files v2 (Rust) | Teil des notify_push-Ökosystems — siehe unten |
Fazit: Kein separates ADA-Upgrade nötig. Nächster sinnvoller Rust-Schritt: notify_push deployen.
Optimierungs-Roadmap (Recherche & Priorität)
Priorität 1 — schnell, hoher Effekt
-
PHP-FPM Limits anheben
pm.max_childrenz. B. 10–15 (abhängig von RAM: ~100 MB/Worker)request_terminate_timeout = 300(oder 600) — verhindert ewig hängende Worker- ggf.
pm.max_requests = 500— Worker regelmäßig recyclen
-
notify_pushevaluieren & deployen ✅ (2026-06-28, Sidecar)- App v1.3.3 manuell, Sidecar
ghcr.io/nextcloud/notify_pushmitnetwork_mode: service:nextcloud occ notify_push:setup— alle Checks grün- Erwartung: deutlich weniger
index.php/204-Traffic in Nginx-Logs (24h beobachten)
- App v1.3.3 manuell, Sidecar
-
APCu vergrößern
apc.shm_sizevon 32 MB → 128 MB (Custom-PHP-Ini im Linuxserver-Config-Volume)
Priorität 2 — mittelfristig
-
Background-Jobs auf System-Cron
- Modus
cron+ crontab auf VM (alle 5 min):
docker exec -u abc nextcloud php /app/www/public/occ background:cron - Entlastet Web-Requests von AJAX-Cron
- Modus
-
NFS / Datenbestand
- 95 % Pool-Auslastung im Blick behalten
occ files:scannur gezielt, nicht pauschal auf 93 TB- Prüfen ob laufende Scans/Previews Worker blockieren (
occ files:scan --status)
-
Nginx FastCGI-Timeouts
fastcgi_read_timeoutim Linuxserver site-conf falls 504 bei langen, legitimen Requests
Priorität 3 — Wartung & Updates
- Minor-Update 34.0.0 → 34.0.1 + Image-Tag pinnen (siehe Migration)
- DB-Indizes —
fs_path_hashaufoc_filecachenur bei Symptomen (ADA-Migrations-Bug 32→33) - Preview-/Scan-Jobs — gezielt, nicht pauschal auf 93 TB NFS
Optional / Client-seitig (nicht zwingend)
- Desktop-Client aktualisieren (weniger fehlerhaftes Verhalten, bessere Push-Unterstützung mit HPB)
- Altes
mirall 3.0.3(User jutta) besonders aggressiv — Update reduziert Last, ist aber kein Muss wenn HPB + FPM stimmen
Docker-Netzwerk (VM 101)
Docker läuft mit "iptables": false in /etc/docker/daemon.json — absichtlich, damit Docker die fest zugewiesenen IPs auf docbr0 (z. B. Nextcloud 10.2.2.253, NPM 10.2.2.254) nicht überschreibt.
Folge: Docker setzt kein NAT/MASQUERADE für Bridge-Netze. Ohne manuelle Regeln haben Container kein ausgehendes Internet (App Store, Docker Mods, curl zu GitHub schlagen fehl).
Lösung (seit 2026-06-28): Systemd-Service docker-nat-rules.service + Skript /usr/local/sbin/docker-nat-rules.sh:
MASQUERADEfür10.2.2.0/24(docbr0) und172.16.0.0/12(Docker-Bridges) →eth0- Läuft nach Boot/
docker.service, ändert nichtiptables: true
sudo systemctl status docker-nat-rules
sudo iptables -t nat -S POSTROUTING
sudo docker exec nextcloud curl -sI https://github.com | head -1
notify_push + Apps im Sync halten
Kein Watchtower auf der VM — Sidecar-Updates laufen über Wartungs-Cron.
| Was | Wie |
|---|---|
| Apps + notify_push-Sync | /usr/local/sbin/nextcloud-maintain.sh (Sonntag 04:30 UTC) |
| Nextcloud-Image / Stack | Dockge: Pull + Redeploy |
| Background-Jobs | root-crontab alle 5 min (background:cron) |
# Manuell ausführen
sudo /usr/local/sbin/nextcloud-maintain.sh
# Log
sudo tail -f /var/log/nextcloud-maintain.log
sudo crontab -l
Ablauf Wartungs-Skript: occ app:update notify_push → occ app:update --all → compose pull notify_push → Sidecar restart → notify_push:setup.
Skripte (VM 101)
Quellen im docu-Repo (Deploy auf die VM nach Bedarf):
| Datei im Repo | Ziel auf VM 101 |
|---|---|
| scripts/vm101-docker-nat-rules.sh | /usr/local/sbin/docker-nat-rules.sh |
| scripts/vm101-docker-nat-rules.service | /etc/systemd/system/docker-nat-rules.service |
| scripts/vm101-nextcloud-maintain.sh | /usr/local/sbin/nextcloud-maintain.sh |
| scripts/vm101-root-crontab.txt | root-crontab (Referenz) |
Installation / Sync vom docu-Repo
# Auf VM 101 (als jean mit sudo), von einem Host mit docu-Clone:
DOCU=/path/to/docu/pve1/scripts
sudo install -m 755 "$DOCU/vm101-docker-nat-rules.sh" /usr/local/sbin/docker-nat-rules.sh
sudo install -m 755 "$DOCU/vm101-nextcloud-maintain.sh" /usr/local/sbin/nextcloud-maintain.sh
sudo install -m 644 "$DOCU/vm101-docker-nat-rules.service" /etc/systemd/system/docker-nat-rules.service
sudo systemctl daemon-reload
sudo systemctl enable --now docker-nat-rules.service
docker-nat-rules.sh
Manuelles NAT bei "iptables": false. Entfernt beim Start alte Duplikat-Regeln und setzt genau zwei MASQUERADE-Regeln.
→ Vollständiger Inhalt: scripts/vm101-docker-nat-rules.sh
docker-nat-rules.service
Systemd-Oneshot, startet nach network-online.target und docker.service.
→ Vollständiger Inhalt: scripts/vm101-docker-nat-rules.service
nextcloud-maintain.sh
Wöchentliche Wartung: Apps updaten, notify_push-Sidecar pull/restart, notify_push:setup als Versions-Check.
→ Vollständiger Inhalt: scripts/vm101-nextcloud-maintain.sh
root-crontab
→ Referenz: scripts/vm101-root-crontab.txt
*/5 * * * * docker exec -u abc nextcloud php /app/www/public/occ background:cron >> /var/log/nextcloud-cron.log 2>&1
30 4 * * 0 /usr/local/sbin/nextcloud-maintain.sh >> /var/log/nextcloud-maintain.log 2>&1
Nützliche Befehle
# Von pve1 — Status in der VM
qm guest exec 101 -- docker stats nextcloud --no-stream
qm guest exec 101 -- docker exec -u abc nextcloud php /app/www/public/occ status
qm guest exec 101 -- docker exec -u abc nextcloud php /app/www/public/occ app:list | grep notify
# PHP-FPM / Logs
qm guest exec 101 -- docker exec nextcloud ps aux | grep php-fpm
qm guest exec 101 -- docker exec nextcloud tail -30 /config/log/php/error.log
qm guest exec 101 -- docker exec nextcloud tail -30 /config/log/nginx/access.log
# Container neu starten (Notfall)
qm guest exec 101 -- docker restart nextcloud
# Stack bearbeiten (auf der VM)
ssh root@192.168.10.10
cd /opt/stacks/nextcloud && docker compose ps
Referenzen
| Thema | URL |
|---|---|
| Memory caching (Redis/APCu) | https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/caching_configuration.html |
| notify_push GitHub | https://github.com/nextcloud/notify_push |
| ADA Engine Blog | https://nextcloud.com/blog/a-new-data-access-architecture-for-nextcloud-introducing-the-ada-engine/ |
| Linuxserver Nextcloud | https://docs.linuxserver.io/images/docker-nextcloud |
Offene Punkte / TODO (Betreiber)
Details und Befehle: migration/nextcloud-optimierung-und-updates.md
Freigabe Phase F+G: migration/nextcloud-tuning-freigabe.md (✅ umgesetzt)
Freigabe notify_push: migration/nextcloud-notify-push-freigabe.md (✅ umgesetzt 2026-06-28)
- PHP-FPM
www2.confangepasst + Container recreate apc.shm_sizeauf 128 MB- System-Cron für
occ background:croneingerichtet - VM-RAM 12 GB
notify_push— Sidecar + App v1.3.3,trusted_proxies+127.0.0.1- Nach Änderungen: Nginx-Access-Log auf Polling-Frequenz prüfen (24h)