Konkrete geplante Änderungen mit Begründung aus offizieller Doku und Messwerten der VM — zur Absegnung vor Umsetzung. Co-authored-by: Cursor <cursoragent@cursor.com>
11 KiB
Freigabe: Nextcloud Tuning (Phase F + G)
Status: ⏳ Zur Absegnung — noch nicht umgesetzt
Erstellt: 2026-06-28
Betrifft: VM 101 ubuntu · Container nextcloud · kein Version-Upgrade
Dieses Dokument beschreibt exakt, was geändert werden soll, warum (mit Quellen), welche Risiken bestehen und wie Rollback funktioniert. Erst nach deiner Freigabe wird umgesetzt.
Bezug: nextcloud-optimierung-und-updates.md · Ist-Zustand: ../pve1/06_ubuntu-vm-nextcloud.md
Kurzfassung
| Was | Warum |
|---|---|
| PHP-FPM: mehr Worker + Timeout | Default pm.max_children=5 — direkte Ursache des CPU-Incidents (offizielle Nextcloud-Doku) |
| APCu: 32 MB → 128 MB | Nextcloud Admin Manual empfiehlt 128 MB Startwert |
| System-Cron alle 5 min | Entlastet Web-Requests; offizielle Empfehlung statt AJAX-Cron |
Nicht in diesem Schritt: notify_push, Image-Update 34.0.1, compose.yml, config.php
Erwartete Unterbrechung: ~5–15 s beim docker restart nextcloud (bestehende Syncs können kurz abbrechen)
Ist-Zustand (gemessen 2026-06-28)
| Parameter | Aktuell | Quelle |
|---|---|---|
pm.max_children |
5 | Container-Default |
pm.start_servers |
2 | Default |
request_terminate_timeout |
nicht gesetzt (∞) | — |
pm.max_requests |
0 (kein Recycle) | Default |
apc.shm_size |
32M | PHP-Default |
| Background-Jobs | vermutlich AJAX/Web (kein System-Cron) | keine root-crontab |
| PHP-FPM Worker RSS (idle/light) | ~85–93 MB | 3 Worker gemessen |
| VM RAM gesamt | 7,7 GB | free -h |
| VM RAM verfügbar | ~4,2 GB | zum Messzeitpunkt |
| Nextcloud-Container idle | ~104 MB | docker stats |
Hinweis: Die VM hostet viele weitere Container (Airsonic ~1 GB, Gitea ~700 MB, Collabora ~530 MB, …). PHP-FPM-Limits deshalb konservativ gewählt, nicht maximal.
Geplante Änderungen
1. Datei: /opt/stacks/nextcloud/config/php/www2.conf
Aktuell: nur Kommentare, [www]-Header — es gelten Container-Defaults.
Geplant (vollständiger neuen Inhalt):
; Edit this file to override www.conf and php-fpm.conf directives and restart the container
; Freigabe 2026-06-28 — siehe docu/migration/nextcloud-tuning-freigabe.md
; Pool name
[www]
; dynamic = empfohlen für Nextcloud (nicht ondemand — sonst Cold-Start bei jedem Client-Poll)
; Quelle: Nextcloud 34 Server Tuning Manual
pm = dynamic
pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 6
; Worker nach 500 Requests recyclen (Memory-Leaks in Extensions)
pm.max_requests = 500
; Hängende Requests nach 300s beenden — verhindert „ewig blockierte“ Worker wie am 28.06.
; Quelle: Nextcloud Server Tuning, gängige Praxis bei WebDAV/Sync
request_terminate_timeout = 300
; Optional: langsame Requests diagnostizieren (Log im Container)
request_slowlog_timeout = 10s
slowlog = /config/log/php/fpm-slow.log
Warum pm.max_children = 12 (nicht 15 oder 30)?
| Rechnung | Wert |
|---|---|
| Gemessene Worker-Größe | ~90 MB |
| 12 Worker Peak | ~1,1 GB nur PHP-FPM |
| + MariaDB, Redis, Nginx im Stack | ~400 MB |
| + andere Container auf der VM | ~3 GB+ |
| Puffer für NFS/OS | nötig |
Formel laut Nextcloud Server Tuning:
pm.max_children = floor(RAM_für_PHP / durchschnittlicher_Worker_RSS)
Offizielle Doku nennt 50–100 MB/Worker und warnt: zu hoch → Swapping, schlimmer als Queuing.
12 ist ein konservativer Startwert für eine Multi-Service-VM (nicht dedizierter Nextcloud-Server). Bei stabilen Metriken kann später auf 15 erhöht werden.
Referenzen:
- Nextcloud 34 — Server tuning / PHP-FPM — Default 5 als „common cause of gateway timeouts“
- Linuxserver www2.conf — offizieller Override-Pfad
2. Datei: /opt/stacks/nextcloud/config/php/php-local.ini
Aktuell:
; Edit this file to override php.ini directives
date.timezone = Etc/UTC
Geplant (Ergänzung):
; Edit this file to override php.ini directives
date.timezone = Etc/UTC
; Nextcloud Admin Manual: Default 32M zu klein, Startwert 128M
; https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/caching_configuration.html
apc.shm_size=128M
Keine weiteren php.ini-Änderungen in diesem Schritt (kein memory_limit, kein OPcache-Tuning — Redis/APCu/OPcache sind bereits aktiv).
Hinweis Linuxserver: Es gibt vereinzelte GitHub-Issues, dass php-local.ini in manchen Image-Versionen von nextcloud.ini überstimmt wird. Nach dem Restart prüfen wir mit php -i | grep apc.shm_size — falls wirkungslos, Alternative: Umgebungsvariable PHP_MEMORY_LIMIT / Image-Dokumentation.
3. System-Cron auf VM 101 (root)
Aktuell: keine root-crontab.
Geplant:
# Nextcloud Background-Jobs — alle 5 Minuten
# Quelle: https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/background_jobs_configuration.html
*/5 * * * * docker exec -u abc nextcloud php /app/www/public/occ background:cron >> /var/log/nextcloud-cron.log 2>&1
Zusätzlich einmalig per occ:
docker exec -u abc nextcloud php /app/www/public/occ background:cron
Das setzt den Modus intern auf Cron (Alternative: Admin-UI → Grundeinstellungen → Hintergrundjobs → Cron).
Warum: AJAX-Cron läuft bei jedem Seitenaufruf mit und erzeugt zusätzliche PHP-Requests. System-Cron ist die offizielle Empfehlung für Produktivbetrieb.
Was bewusst NICHT geändert wird
| Item | Grund |
|---|---|
compose.yml / Docker-Image |
kein Update in diesem Schritt |
config.php |
Redis/APCu bereits korrekt konfiguriert |
Nginx default.conf |
keine Timeout-Änderung (erst bei Bedarf) |
| notify_push | eigene Freigabe-Phase (größerer Eingriff) |
| Client-Updates | optional, nicht nötig für Server-Fix |
| MariaDB-Tuning | out of scope |
Risiken & Mitigation
| Risiko | Einschätzung | Mitigation |
|---|---|---|
| Kurze Unterbrechung beim Restart | gering | nachts / bei wenig Sync-Traffic |
request_terminate_timeout=300 bricht langsame Syncs ab |
mittel | 300s ist Standard für WebDAV; NFS-Ops >5min würden abbrechen — Slowlog zeigt das |
| 12 Worker reichen nicht | mittel | Monitoring; bei Bedarf auf 15 erhöhen |
| 12 Worker zu viel RAM | gering | konservative Rechnung; kein Swap auf VM (0 B!) — bei OOM würde Kernel Prozesse killen |
| APCu 128M „verschwendet“ RAM | sehr gering | 96 MB Mehrverbrauch vs. Default |
| Cron-Job schlägt fehl | gering | Log /var/log/nextcloud-cron.log; Admin-UI zeigt letzten Cron-Lauf |
Rollback
| Änderung | Rollback |
|---|---|
www2.conf |
alten Inhalt wiederherstellen (leer + [www]) → docker restart nextcloud |
php-local.ini |
apc.shm_size-Zeile entfernen → Restart |
| Crontab | crontab -e → Zeile löschen |
Kein DB-Rollback nötig. Kein Image-Downgrade.
Verifikation nach Umsetzung (Checkliste)
# 1. PHP-FPM-Werte
docker exec nextcloud cat /etc/php84/php-fpm.d/www.conf | grep -E "^pm\.|^request_terminate"
# 2. APCu
docker exec nextcloud php -i | grep apc.shm_size
# 3. Cron-Modus
docker exec -u abc nextcloud php /app/www/public/occ config:system:get backgroundjobs_mode
# 4. Cron-Log (nach 5–10 min)
tail -20 /var/log/nextcloud-cron.log
# 5. Last / Worker
docker exec nextcloud ps aux | grep "php-fpm: pool"
docker stats nextcloud --no-stream
# 6. Keine pm.max_children-Warnung mehr in php error.log
docker exec nextcloud tail -20 /config/log/php/error.log
Erfolgskriterien:
pm.max_children = 12aktivapc.shm_size = 128Maktiv- Cron-Log zeigt regelmäßige Läufe ohne Fehler
- Kein erneutes „server reached pm.max_children (5)“ im Log
- CPU unter Normal-Last stabil (keine 5 Worker bei 100 % über Stunden)
Umsetzungs-Befehle (nach Freigabe)
Werden erst nach OK ausgeführt — zur Transparenz hier dokumentiert:
# Auf pve1 via Guest Agent oder SSH root@192.168.10.10
# --- www2.conf schreiben ---
cat > /opt/stacks/nextcloud/config/php/www2.conf << 'EOF'
; Edit this file to override www.conf and php-fpm.conf directives and restart the container
; Freigabe 2026-06-28 — siehe docu/migration/nextcloud-tuning-freigabe.md
[www]
pm = dynamic
pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500
request_terminate_timeout = 300
request_slowlog_timeout = 10s
slowlog = /config/log/php/fpm-slow.log
EOF
# --- php-local.ini ergänzen ---
grep -q 'apc.shm_size' /opt/stacks/nextcloud/config/php/php-local.ini || \
echo 'apc.shm_size=128M' >> /opt/stacks/nextcloud/config/php/php-local.ini
# --- Container restart ---
docker restart nextcloud
# --- Cron ---
(crontab -l 2>/dev/null | grep -v 'occ background:cron'; \
echo '*/5 * * * * docker exec -u abc nextcloud php /app/www/public/occ background:cron >> /var/log/nextcloud-cron.log 2>&1') | crontab -
docker exec -u abc nextcloud php /app/www/public/occ background:cron
Freigabe
| ☐ | Freigegeben — Phase F+G wie oben umsetzen |
| ☐ | Anpassung — z. B. pm.max_children auf 15 statt 12 |
| ☐ | Abgelehnt / später |
Freigegeben von: _______________
Datum: _______________
Anmerkungen: _______________
Nächste Phase (separate Freigabe)
notify_push (Rust HPB) — eigener Change-Request, weil:
- compose.yml-Erweiterung
- NPM Custom Location
/push - neuer Container + App-Installation
Siehe nextcloud-optimierung-und-updates.md §7.
Quellen (Web-Recherche)
| Thema | URL |
|---|---|
| PHP-FPM Tuning (offiziell NC 34) | https://docs.nextcloud.com/server/stable/admin_manual/installation/server_tuning.html |
| APCu 128M Empfehlung | https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/caching_configuration.html |
| Background Jobs / Cron | https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/background_jobs_configuration.html |
| Linuxserver www2.conf / php-local.ini | https://github.com/linuxserver/docker-nextcloud/issues/68 |
| PHP-FPM max_children Praxis | https://perlod.com/tutorials/php-fpm-max-children/ |