Mittwochabend ist bei mir Wartungsfenster. Nicht aus Prinzip, sondern weil ich es mir an einem Freitag im Februar selbst beigebracht habe: Ich hatte vier Container aktualisiert, danach lief die Fotoverwaltung nicht mehr, und ich habe zwei Tage Wochenende damit verbracht, eine Datenbank zu reparieren, deren Schema das alte Image nicht mehr kannte. Seitdem steht das Update in der Wochenmitte, dann sind noch zwei Abende Puffer da.
Dieser Beitrag ist die Reihenfolge, die ich mir danach aufgeschrieben habe – und die Erklärung, warum ausgerechnet der Rollback bei Containern nicht so funktioniert, wie alle annehmen.
Der Fehler steckt schon im Compose-File

Wenn in deiner compose.yaml ein Image ohne Versionsangabe steht, holt sich Docker beim nächsten Pull stillschweigend die neueste Version – egal, ob das ein Bugfix oder ein Sprung über zwei Hauptversionen ist.
# So nicht - "latest" ist keine Version, sondern eine Lotterie
services:
app:
image: beispiel/app
# Besser: Hauptversion festnageln, Patches darf er holen
services:
app:
image: beispiel/app:5.2
# Für alles, was Daten haelt: exakt festnageln
services:
db:
image: postgres:16.4Der Grund ist nicht Docker, sondern die Anwendungen. Viele Projekte unterstützen nur den Sprung auf die nächsthöhere Hauptversion – von 29 auf 30, nicht von 29 auf 31. Wer latest fährt und zwei Monate nicht aktualisiert hat, springt beim nächsten Pull möglicherweise über eine Version, und die Datenbankmigration verweigert den Dienst. Das ist genau der Fall, der mir den Februar-Freitag gekostet hat.
Pro-Tipp: Datenbank-Images und Anwendungs-Images sind zwei verschiedene Dinge. Die Anwendung darfst du regelmäßig anheben. Die Datenbank bleibt stehen, bis die Anwendung ausdrücklich eine neuere verlangt. Ein Postgres-Hauptversionswechsel ist eine Datenmigration, kein Update – der gehört an einen eigenen Termin.
Die Reihenfolge, die ich jetzt einhalte
Sechs Schritte, immer dieselben, immer in dieser Folge. Der erste ist der, den ich früher ausgelassen habe.
- Changelog lesen. Nicht alles, nur die Abschnitte „Breaking Changes“ und „Upgrade Notes“. Zwei Minuten pro Dienst. Wenn dort ein Satz über Konfigurationsänderungen steht, ist das Update heute kein Update, sondern ein Termin für nächste Woche.
- Datenbank sichern – mit dem Werkzeug der Datenbank, nicht mit einem Dateikopie-Backup. Dazu unten mehr, das ist der entscheidende Punkt.
- Snapshot ziehen, wenn der Dienst in einer VM oder einem LXC-Container liegt.
- Images holen, aber noch nicht starten. So merkst du, ob der Download klappt, bevor du den laufenden Dienst anhältst.
- Einen Dienst starten, nicht alle. Danach Logs lesen, Weboberfläche aufrufen, eine Aktion durchklicken.
- Aufräumen – aber erst, wenn der neue Stand einen Tag gelaufen ist. Das alte Image ist dein Rückweg.
# 4. Images holen, ohne etwas anzuhalten
docker compose pull
# 5. Einen Dienst neu starten und zusehen
docker compose up -d app
docker compose logs -f --tail=100 app
# Welche Version laeuft jetzt wirklich?
docker compose images
# 6. Erst am naechsten Tag: alte Images wegwerfen
docker image pruneDie Dokumentation zu docker compose pull beschreibt genau diese Trennung: Images holen, ohne Container zu starten. Das ist der Grund, warum ich nie docker compose up -d --pull always über den ganzen Stack laufen lasse – dabei passiert beides gleichzeitig und bei allen Diensten auf einmal. Wer bei Compose noch am Anfang steht, findet die Grundlagen in meinem Compose-Tutorial, und die ganze Reihe in der Docker-Serienübersicht.
Warum der Rollback bei Containern nur halb funktioniert
Das ist der Teil, den ich vor dem Februar nicht verstanden hatte. Die Werbebotschaft lautet: Container sind unveränderlich, du setzt einfach die alte Version wieder ein. Für den Anwendungscode ist das richtig. Für die Daten ist es falsch.
Beim ersten Start einer neuen Version wandert die Datenbank über eine Migration auf ein neues Schema – neue Spalten, umbenannte Tabellen, geänderte Datentypen. Diese Migration ist in den meisten Projekten eine Einbahnstraße. Setzt du danach das alte Image ein, findet die alte Anwendung ein Schema vor, das sie nicht kennt, und verweigert den Start. Dein Rollback besteht also aus zwei Teilen:
- Image zurück – Versionsnummer im Compose-File auf den alten Wert,
docker compose up -d. Das ist der einfache Teil. - Datenbank zurück – aus dem Dump, den du vor dem Update gezogen hast. Ohne diesen Dump ist der Rollback nicht möglich, Snapshot hin oder her.
# Postgres-Dump VOR dem Update - das ist die eigentliche Versicherung
docker compose exec -T db pg_dump -U app -d appdb \
> ~/dumps/appdb-$(date +%F).sql
# MariaDB/MySQL
docker compose exec -T db mariadb-dump -u root -p"$PW" appdb \
> ~/dumps/appdb-$(date +%F).sql
# Zurueckspielen, falls es sein muss
cat ~/dumps/appdb-2026-10-14.sql | docker compose exec -T db psql -U app -d appdbEin Dateisystem-Backup des Datenverzeichnisses einer laufenden Datenbank ist kein Ersatz dafür. Es kann einen inkonsistenten Zustand erwischen, und du merkst das erst beim Zurückspielen. Dasselbe Prinzip – erst der funktionierende Restore macht das Backup fertig – habe ich an anderer Stelle schon beim Planen von RTO und RPO und bei der 3-2-1-Regel beschrieben. Im Homelab ist es die Stelle, an der es am schnellsten weh tut.
Snapshots: nützlich, aber nicht das, was viele denken
Wenn deine Dienste in einer VM oder einem LXC-Container unter Proxmox laufen, ist ein Snapshot vor dem Update die bequemste Rückfallebene: ein Klick, und der ganze Zustand liegt fest. Die Proxmox-Dokumentation zu Backup und Restore beschreibt die Unterschiede zwischen den Modi; wichtig ist für uns nur eine Einschränkung, und die wird gern überlesen.
Ein Snapshot umfasst nur, was auf den virtuellen Platten dieser VM liegt. Wenn deine Container-Volumes per NFS oder SMB auf dem NAS liegen – und das ist im Homelab die Regel –, sind die Daten im Snapshot nicht enthalten. Du rollst dann die Anwendung zurück, während die Daten auf dem neuen Stand bleiben. Das ist schlimmer als kein Rollback, weil du es nicht sofort siehst. Wer gerade erst anfängt, findet die Grundstruktur in meinem Proxmox-Einsteiger-Guide; welche Dienste sich überhaupt lohnen, steht in Homelab mit Docker für Heimanwender.
Pro-Tipp: Schreib in das Compose-File als Kommentar über jeden Dienst, wo seine Daten liegen und wie man sie sichert. Zwei Zeilen. Beim nächsten Update um 22 Uhr willst du das nicht erst herausfinden.
Watchtower: warum ich es nur noch zuschauen lasse
Watchtower überwacht die Registry und startet Container automatisch mit dem neuen Image neu. Das klingt wie die Lösung für genau dieses Problem, und für einen Teil meiner Dienste ist es das auch.
- Geeignet: zustandslose Kleinigkeiten – ein Reverse Proxy, ein DNS-Filter, ein Monitoring-Agent, ein Dienst, dessen kompletter Zustand in einer Konfigurationsdatei steht.
- Nicht geeignet: alles mit Datenbank. Fotoverwaltung, Dokumentenarchiv, Cloud-Speicher, Notizen. Dort entscheidet die Migration, und die soll kein Zeitplan um drei Uhr nachts auslösen.
- Der Kompromiss: Watchtower im Beobachtungsmodus laufen lassen. Es prüft dann nur, ob neue Images verfügbar sind, und schickt eine Nachricht, statt zu aktualisieren. Damit habe ich am Mittwoch eine Liste und entscheide selbst.
Was ebenfalls nicht automatisiert gehört: alles, was nach außen erreichbar ist. Ein Dienst, der im Internet hängt, braucht Updates schneller – aber eben beobachtet, nicht blind. Wie schnell man sich dabei einen offenen Port einbaut, habe ich beim Fernsteuern des 3D-Druckers aufgeschrieben, und die Grundabsicherung des Netzes steht in der Router-Checkliste.
Wie oft ist oft genug?
„Immer sofort“ ist genauso falsch wie „einmal im Jahr“. Ich fahre inzwischen drei Geschwindigkeiten, und die Einteilung richtet sich nicht nach meiner Neugier, sondern danach, was passiert, wenn der Dienst ausfällt oder angegriffen wird.
- Sofort, auch außerhalb des Fensters: alles, was von außen erreichbar ist, plus Reverse Proxy und alles, wofür eine Sicherheitslücke mit CVE-Nummer gemeldet ist. Dafür reiße ich auch mittwochs um elf noch einmal das Notebook auf.
- Monatlich im Wartungsfenster: die Anwendungen selbst – Dokumentenarchiv, Fotoverwaltung, Smart-Home-Zentrale. Ein Monat Abstand bedeutet einen Versionssprung, nicht fünf, und das ist der Punkt, an dem Migrationen zuverlässig funktionieren.
- Quartalsweise mit Termin: Datenbanken, Basis-Images, Betriebssystem der VM. Das sind die Updates, bei denen ich eine Stunde Zeit einplane und nicht zwanzig Minuten.
Der Fehler, der mir dabei am längsten unterlaufen ist: Dienste, die „einfach laufen“, vergisst man. Mein DNS-Filter war vierzehn Monate auf demselben Stand, weil er nie Probleme gemacht hat. Seitdem steht jeder Container mit Datum der letzten Aktualisierung in meiner Liste – wer alles im Netz mitdokumentiert, findet solche Lücken schneller, wie ich beim Dokumentieren des Heimnetzes beschrieben habe.
Mein Wartungsfenster in zwanzig Minuten
- Liste der verfügbaren Updates ansehen (Watchtower-Meldung oder
docker compose pullim Trockenlauf) - Changelogs der betroffenen Dienste auf Breaking Changes prüfen
- Datenbank-Dumps ziehen, Dateigröße kurz anschauen (0 Byte passiert öfter als man denkt)
- Snapshot der VM oder des LXC anlegen, Datenpfade außerhalb mitdenken
docker compose pull, dann Dienste einzeln starten- Logs der ersten zwei Minuten lesen, eine echte Aktion in der Oberfläche testen
- Versionsstände und Datum in eine Datei schreiben, neben das Compose-File
- Am nächsten Abend: lief alles? Dann alte Images aufräumen
Was mich am meisten überrascht hat: Der zeitaufwendige Teil ist nicht das Update, sondern das Lesen. Die Befehle laufen in zwei Minuten durch, die Changelogs kosten zehn. Und genau diese zehn Minuten haben mir seit Februar zwei Abende gerettet, an denen ich ein Update verschoben habe, weil in den Upgrade Notes ein Satz stand, den ich nicht an einem Mittwoch um halb elf verstehen wollte.
Dass es überhaupt eine Rückfallebene braucht, hat übrigens einen unangenehmen Beigeschmack, wenn der Strom ausfällt, während die Migration läuft. Deshalb hängt mein Server an einer kleinen USV – welche Größe dafür reicht, steht in meinem Beitrag zur USV für NAS und Homelab. Die Windows-Seite derselben Routine, also der Umgang mit dem monatlichen Patchday, steht in Der Tag nach dem Patchday.
