❌

Normale Ansicht

Wie ich eine alte Nextcloud-Installation mit Docker gerettet habe

03. November 2026 um 16:24

Manchmal braucht es eine reißerische Überschrift, um das eigene Versagen zu übertünchen. Was war passiert? Wie in Ubuntu-Server-Update von 24.04 auf 26.04 beschrieben, habe ich vor ein paar Tagen einen Ubuntu-Server auf Version 26.04 aktualisiert. Dort lief (und läuft weiterhin) unter anderem Nextcloud.

Was ich bei meinem Upgrade übersehen hatte: Ich hatte meine Nextcloud-Installation in den vergangenen 18 Monaten sträflich vernachlässigt. Alles funktionierte, an Updates hatte ich nicht gedacht. Genau das ist mir mit dem Ubuntu-Upgrade auf die Füße gefallen. Meine Nextcloud-Clients konnten keine Verbindung mehr herstellen. Die Webseite zeigte kurz und bündig:

This version of Nextcloud is not compatible with PHP>=8.5. 
You are currently running 8.5.4

Ein kurzer Test ergab, dass Nextcloud 31 installiert war. Die erste Version, die PHP 8.5 unterstützt, ist aber Nextcloud 33. Aktuell wäre gar Nextcloud 35 …

Das klingt nach einem trivialen Problem, aber das täuscht: Für den Upgrade-Prozess ist ein PHP-Script zuständig, und dieses verweigert mit meiner neuen PHP-Version die Ausführung. Außerdem muss Nextcloud immer Version für Version aktualisiert werden. Eine direkte Abkürzung von Version 31 zu 35 ist nicht zulässig.

In der Vergangenheit hatte ich schon mehrfach das Problem, dass ich Nextcloud nicht aktualisieren konnte, weil PHP zu alt war. Auf die Idee, dass es auch den umgekehrten Fall geben könnte (PHP zu neu), bin ich nicht gekommen.

Docker ist die Lösung

Ich brauchte also auf meinem frisch aktualisierten Server eine alte PHP-Version. Dafür gibt es (inoffizielle) Repositories, aber die wollte ich nicht verwenden. PHP 8.3 oder 8.4 sollte ja nur für ein paar Minuten ein Script ausführen. Zu Hilfe kam mir einerseits Docker, das auf dem Server sowieso installiert ist, und andererseits Claude Code, von dem ich mir mit dem folgenden Prompt eine detaillierte Anleitung erstellen ließ.

/var/www/html/nextcloud contains Nextcloud 31.0.4. My problem: I upgraded to PHP 8.5, but Nextcloud 31 is incompatible with this PHP version. I need to upgrade to Nextcloud version 33 (first PHP 8.5 compatible version), keeping all data. Docker is available to run an older PHP version. Line out an upgrade plan.

Die Grundidee besteht darin, mit einem Dockerfile ein Image mit PHP 8.3 zur Ausführung des Upgrades zu erstellen:

# Dockerfile
FROM php:8.3-cli
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions \
 && install-php-extensions pdo_mysql gd intl zip bcmath gmp apcu exif opcache pcntl sysvsem imagick
RUN printf "memory_limit=2G\napc.enable_cli=1\n" > /usr/local/etc/php/conf.d/nc.ini

Das Image wird im Verzeichnis mit dem Dockerfile mit dem folgenden Kommando erzeugt:

sudo docker build -t nc-php83 .

Auf der Basis dieses Images kann das Nextcloud-Kommando occ mit dem folgenden Script nc-occ ausgeführt werden:

#!/bin/sh
exec sudo docker run --rm -it --network host \
  --user "$(id -u www-data):$(id -g www-data)" \
  -v /var/www/html/nextcloud:/var/www/html/nextcloud \
  -v /var/run/mysqld:/var/run/mysqld \
  -w /var/www/html/nextcloud nc-php83 \
  php -d pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock occ "$@"

Das Script bindet in den temporären Container das Nextcloud-Verzeichnis unter demselben Pfad wie auf dem Host ein, damit die absoluten Pfade in der config.php weiter stimmen. Es läuft mit der UID von www-data, damit die Dateirechte passen, und nutzt --network host, damit die lokale Datenbank erreichbar ist. Code, Konfiguration und Daten bleiben also auf dem Host, und im Container läuft nur php occ.

Die größte Hürde war die Datenbankverbindung. Der erste Test mit nc-occ status scheiterte mit SQLSTATE[HY000] [2002] No such file or directory. Die Ursache: Das Debian-PHP sucht den MySQL-Socket standardmäßig unter /var/run/mysqld/mysqld.sock, das offizielle Docker-Image tut das nicht. Es reicht deshalb nicht, den Socket-Ordner per -v /var/run/mysqld:/var/run/mysqld einzubinden, man muss PHP den Pfad auch mit -d pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock mitteilen.

Der weitere Ablauf ist in der schon erwähnten Anleitung detailliert ausgeführt. Selbstredend habe ich vorher ein Backup meiner Daten gemacht (also das Verzeichnis /var/www/html/nextcloud/data sowie die MySQL-Datenbank).

Danach habe ich diese Anleitung Schritt für Schritt abgearbeitet. Theoretisch wäre es auch denkbar, diese Aufgabe agentisch an Claude Code zu delegieren; dazu hätte ich Claude Code aber root-Rechte geben müssen. So mutig war ich dann doch nicht.

Später habe ich Nextcloud in der Web-UI weiter auf die Versionen 34 und 35 aktualisiert. Zum Schluss habe ich aufgeräumt, also insbesondere /var/www/html/nextcloud/data/updater-xxx/* sowie das Docker-Imgage für PHP 8.3 gelöscht.

❌