
🌐 Auch auf: English · Français · Español
Deep Dive aus der Reihe rund um die Ansible-Tour. Niveau: fortgeschrittene Linux-Administration. Die Tour erklärt die Rollen; die Deep Dives erklären die Technik darunter – wie sie funktioniert, warum sie hier ist, was genau dieses Setup damit macht, wie man sie im Alltag betreibt und was es sonst noch gegeben hätte.
Auf diesem Setup laufen zwei Nextcloud-Server, einer für eine Organisation mit rund 150 Konten und fast 400 GB Dateien, einer für eine kleine Gruppe. Beide entstehen aus denselben Rollen (Teil 4 der Tour). Dieser Beitrag erklärt, wie Nextcloud aufgebaut ist, wie die Teile zwischen Host und Cluster verteilt sind und was der Betrieb bisher gelehrt hat.
🧭 Wie Nextcloud funktioniert
Eine PHP-Anwendung, viele Eingänge
Nextcloud ist PHP. Jede Browserseite, jede WebDAV-Anfrage eines Sync-Clients und jeder API-Aufruf der Mobil-Apps ist ein PHP-Aufruf über nginx an PHP-FPM. Die Dateien selbst liegen in einem Datenverzeichnis; die Datenbank kennt jede Datei über die Tabelle file cache – Name, Größe, ETag, Rechte –, damit Verzeichnislisten nie die Platte anfassen müssen.
Sperren und Caches
Wenn zwei Clients dieselbe Datei ändern, entscheidet das transaktionale File-Locking, wer gewinnt. Die Sperren müssen für jeden PHP-Prozess sofort sichtbar sein, deshalb liegen sie in Redis. Daneben cacht APCu pro Prozess und Redis prozessübergreifend.
Hintergrundjobs
Aufräumen, Papierkorb- und Versionsablauf, Benachrichtigungen, Update-Prüfungen für Apps, Vorab-Erzeugung von Vorschaubildern – Nextcloud führt eine Job-Warteschlange in der Datenbank. Irgendetwas muss regelmäßig cron.php ausführen, um sie abzuarbeiten; Nextcloud empfiehlt alle fünf Minuten.
Push, Vorschaubilder, Office
- notify_push ist ein kleiner Rust-Daemon, der in einer App mitgeliefert wird. Clients halten eine WebSocket-Verbindung zu ihm offen und erfahren Änderungen sofort, statt alle 30 Sekunden nachzufragen.
- Vorschaubilder sind Thumbnails, erzeugt beim ersten Ansehen oder vorab durch die App Preview Generator, und abgelegt im App-Datenordner.
- Nextcloud Office ist die App richdocuments plus ein Collabora-Online-Server. Der Browser lädt den Editor von Collabora; Collabora holt und speichert das Dokument bei Nextcloud über das WOPI-Protokoll, mit einem Token pro Sitzung.
Apps und occ
Fast alles jenseits von Dateien ist eine App – Kalender, Kontakte, Talk, Gruppenordner. occ ist das Kommandozeilenwerkzeug für die gesamte Administration: Status, Upgrades, Wartungsmodus, Konfiguration, Datei-Scans, Datenbank-Reparaturen.
🛡️ Warum es hier ist
- Dateien, Kalender, Kontakte und Office an einem Ort, für Menschen, die nicht wissen müssen sollten, was WebDAV ist.
- Die Daten bleiben auf den eigenen Servern der Organisation. Kein Anbieter entscheidet über Zugang, Preise oder Funktionen.
- Ein Ökosystem. Apps für fast jeden Bedarf, Clients für jede Plattform, eine große Community.
🔧 Was dieses Repository macht
Was wo läuft
| Komponente | Wo | Rolle |
|---|---|---|
| nginx + PHP-FPM + Exporter | Pod nextcloud | next_k3s_deploy |
| notify_push | Eigenes Deployment, gleiches Image | next_k3s_deploy |
| Collabora Online | Eigenes Deployment | next_k3s_deploy |
| Hintergrundjobs | CronJob alle 5 Min. | next_k3s_deploy |
| MariaDB | Host, mysqld_t | next_mariadb |
| Redis | Host, redis_t | next_redis |
| Einstellungen, Apps, WOPI, Passwortrichtlinie | über occ | next_config |
Die schweren, wertvollen Komponenten – Datenbank und Daten – liegen auf dem Host, mit voller systemd-Sandbox und eigenen SELinux-Domains. Die austauschbaren – PHP, Collabora, der Push-Daemon – laufen im Cluster. Kubernetes-Services ohne Selektor, die auf die Knoten-IP zeigen, machen MariaDB und Redis für die Pods unter den Namen mariadb und redis erreichbar; nftables erlaubt den jeweiligen Port nur aus dem Pod-Netz. Der PHP-Code (/srv/nextcloud-www) und die Daten (/data) sind hostPath-Volumes mit eigenen SELinux-Labels.
Konfiguration in Schichten
Nextcloud liest config.php und danach jede *.config.php im Konfigurationsverzeichnis in alphabetischer Reihenfolge, spätere Dateien gewinnen. Das Repository nutzt das: custom.config.php aus einer ConfigMap trägt die Einstellungen (Caches, Vorschaubilder, Proxys, Logging), redis.config.php aus einem Secret das Redis-Passwort. Beide sind mit subPath eingehängt, das sich in einem laufenden Pod nie aktualisiert; eine Prüfsumme über alles Eingehängte ist eine Annotation am Pod, sodass eine Änderung ihn neu ausrollt. Diese Prüfsumme deckte ursprünglich nur die ConfigMaps ab – eine neue Vorschaubild-Einstellung lag einmal einen Tag lang in der ConfigMap, während der Pod noch die alte Datei nutzte. Seit dieser Reihe deckt sie auch das Secret ab, nachdem der Redis-Deep-Dive gezeigt hatte, dass ein gewechseltes Passwort den Pod nicht erreicht hätte.
Collabora
extra_params: --o:ssl.enable=false --o:ssl.termination=true
--o:num_prealloc_children=10 --o:per_document.max_concurrency=6TLS endet am Ingress, also läuft Collabora dahinter mit reinem HTTP und wird darüber informiert. num_prealloc_children hält so viele Dokumentprozesse vorab gestartet; das Öffnen eines Dokuments nimmt einen, und ist keiner bereit, wartet der Benutzer auf einen frisch startenden. Das gelegentliche „Laden fehlgeschlagen, erneuter Versuch klappt“ direkt nach einem Collabora-Neustart ist genau das. Der größere Server hält zehn bereit, der kleinere sechs. next_config setzt die WOPI-Allowlist auf das Pod-Netz – nur Collabora darf die WOPI-Endpunkte aufrufen – und lässt Nextcloud nach jeder Collabora-Änderung dessen Discovery-Dokument neu einlesen.
Ein Installationsdetail kostete einen Nachmittag: occ app:install richdocuments schnitt beim Entpacken reproduzierbar eine Datei der App ab, und die Integritätsprüfung schlug danach fehl. Die Rolle lädt das Tarball deshalb selbst aus dem App Store, entpackt es mit tar und prüft die Signaturen der App mit occ integrity:check-app.
Zwei Arten von Updates
Ein Versionswechsel ist ein neues Image-Tag in versions.yml und ein Lauf des Haupt-Playbooks; der Entrypoint des Containers führt beim Start occ upgrade aus. Nextcloud selbst verweigert das Überspringen einer Major-Version, ein Sprung von 32 auf 34 sind also zwei Schritte. Neu gebaute Images – Docker Hub baut unveränderte Tags für Korrekturen am Basis-Image neu, und K3s zieht von sich aus nie neu – sind die Aufgabe von nextcloud-update.yml. Es läuft nicht ohne --limit (ein Server nach dem anderen), startet nicht auf einer Instanz im Wartungsmodus oder mit ausstehendem Datenbank-Upgrade, startet nur Deployments neu, deren Image sich wirklich geändert hat, führt occ upgrade als Sicherheitsnetz aus, aktualisiert die Apps, startet ein zweites Mal neu (OPcache prüft keine Zeitstempel, siehe den PHP-FPM-Deep-Dive) und prüft den Status. Scheitert etwas, sammelt ein Rescue-Block den Zustand für eine Entscheidung von Hand. Beide Server laufen mit Nextcloud 34.
Isolation
- Eine NetworkPolicy lässt Collabora nur mit Nextcloud und DNS sprechen und Verbindungen nur von Nextcloud und dem Knoten annehmen. Der Nextcloud-Pod und der Push-Daemon haben noch keine – anders als beim Blog, wo jeder Pod isoliert ist. In einem Cluster, der sonst nichts enthält, ist das keine offene Tür, aber eine fehlende Schicht; gefunden beim Schreiben dieses Artikels und vorgeschlagen.
- Eine Admission-Policy lässt nur Images aus einer Allowlist von Registries zu – auch das Image des ACME-Solvers von cert-manager, der in diesem Namespace läuft; beim Blog ließ sein Fehlen einmal eine Zertifikatsanfrage ohne jede Fehlermeldung hängen.
- Keine Service-Account-Tokens in den Pods – nichts darin spricht mit der Kubernetes-API.
- ClamAV scannt die Dateien im Hintergrund um 04:30, Vorschaubilder und Medienformate ausgenommen – vor dieser Änderung war der Scan die Ursache eines Servers, der ohne sichtbaren Grund als „beschäftigt“ erschien.
📊 Gemessen
| Nextcloud A | Nextcloud B | |
|---|---|---|
| Version | 34.0.5 | 34.0.5 |
| Konten / aktiv in den letzten 7 Tagen | 152 / 27 | 26 / 1 |
| Daten | 388 GB | 16 GB |
| Einträge im File Cache | 73.061 | 7.415 |
| Apps aktiviert / deaktiviert | 43 / 22 | 61 / 8 |
| Hintergrundjob-Lauf (cron.php) | 8–16 s alle 5 Min. | 6–8 s alle 5 Min. |
| Längster einzelner Job | 133 s (Update-Prüfung) | 59 s (Update-Prüfung) |
| Admin-Übersicht | alle Prüfungen grün | ein Log-Fehler, erwartet (siehe unten) |
Der File Cache des größeren Servers hatte nach der Migration vom alten Server mehr als zehnmal so viele Einträge: Die wiederhergestellte Datenbank enthielt noch den gesamten Dateiindex des alten Servers, und occ files:cleanup tat nichts, solange die Storage-Zeile des alten Pfads existierte. Ein Viertel des Rests gehörte zu Überbleibseln einer früher genutzten Office-App. Beides wurde entfernt – nach einem Backup und nach dem Zählen der lebenden Zeilen, denn Daten deaktivierter Apps bleiben grundsätzlich erhalten, falls jemand sie zurückhaben will.
🧰 Betrieb im Alltag
occ() { k3s kubectl -n nextcloud exec deploy/nextcloud -c nextcloud-fpm -- \
runuser -u www-data -- php /var/www/html/occ "$@"; }
occ status
occ setupchecks # the admin overview, on the command line
occ maintenance:mode --on # before anything that touches data
occ files:scan --path="/alice/files" # after files were changed outside Nextcloud
occ db:add-missing-indices
occ background-job:list --limit=20
occ app:list --disabledErwartete Warnungen
- „Fehler im Protokoll“ auf dem kleineren Server: ein Datenbankfehler um 03:30 – der nächtliche Neustart, bei dem ein Hintergrundjob-Pod
mariadbnicht auflösen konnte. Harmlos, bleibt aber in der Übersicht, bis das Log rotiert. - „Office konnte nicht geladen werden, erneuter Versuch klappt“ direkt nach einem Neustart: Collabora hatte noch keinen vorgestarteten Prozess.
- Integritätswarnungen nach einer händischen Änderung im App-Verzeichnis sind echt: Nextcloud signiert seinen Code, und jede bearbeitete Datei fällt auf. App-Code nie an Ort und Stelle bearbeiten.
Backups und Wiederherstellung
Jede Nacht holt ein Backup-Rechner den Datenbank-Dump, config.php und das Datenverzeichnis per SSH und versioniert sie 365 Tage lang. Eine Wiederherstellung ist der umgekehrte Weg plus occ maintenance:data-fingerprint, das den Sync-Clients mitteilt, dass sich der Serverstand geändert hat, damit sie nicht löschen, was sie für neu halten.
🆘 Spickzettel: Symptom → Befehl
Die Kurzfassung dieses Artikels für den Moment, in dem etwas nicht stimmt. Auf dem Host als root ausführen; <…> sind Platzhalter. occ und wp sind die Shell-Funktionen aus den Deep Dives zu Nextcloud und WordPress.
| Symptom | Befehl |
|---|---|
| Erster Blick | occ status |
| Hängt im Wartungsmodus | occ maintenance:mode --off |
| Außerhalb geänderte Dateien fehlen | occ files:scan --path="/<user>/files" |
| Alter Code nach einem App-Update | k3s kubectl -n nextcloud rollout restart deployment/nextcloud |
| Hintergrundjobs hängen hinterher | occ background-job:list --limit=20 |
| Office-Dokumente öffnen nicht | k3s kubectl -n nextcloud logs deploy/collabora --tail=50 |
| Clients synchronisieren nicht sofort | occ notify_push:self-test |
| Vorschaubilder fressen die Platte | occ preview:cleanup # never rm: previews live in the database |
| Warnungen nach einem Upgrade | occ db:add-missing-indices |
| Nach dem Zurückspielen eines Backups | occ maintenance:data-fingerprint |
🔭 Wie es weitergeht
- Nextcloud 35, sobald die erste Punktversion da ist, zuerst auf dem kleineren Server.
- S3 als primärer Speicher würde die Daten von der Host-Platte unabhängig machen – erst mit mehr als einem Knoten relevant.
- Das Talk High-Performance Backend, falls Videoanrufe einmal mehr als gelegentlich werden.
⚖️ Alternativen – und warum Nextcloud
| Option | Stärke | Warum nicht hier |
|---|---|---|
| Seafile | Viel schnellerer Sync, Speicherung auf Blockebene | Weniger Groupware-Funktionen, Daten nicht als normale Dateien gespeichert. |
| ownCloud Infinite Scale | Go, kein PHP, keine Datenbank | Andere Architektur, kleineres App-Ökosystem, hieße eine Migration von allem. |
| Eine proprietäre Cloud | Nichts zu betreiben | Daten und Zugang entscheidet ein Anbieter – das Gegenteil des Ziels. |
| Nextcloud | Funktionsumfang, Apps, Clients, Community, die vorhandenen Daten | Gewählt. |
Nextcloud ist nicht schwer zu installieren; es ist anspruchsvoll, es gut zu betreiben, weil es ein Dutzend Dienste ist, die so tun, als wären sie einer. Sie nach „wertvoll oder austauschbar“ aufzuteilen – Datenbank und Dateien auf dem Host, PHP und Office im Cluster – machte jeden Teil leichter zu durchschauen. Die Fehler in diesem Beitrag lagen fast alle an den Nahtstellen dazwischen.


