PostgreSQL Datenbank im Docker Container upgraden
So gut wie jede Serveranwendung, die ich betreibe, läuft in einem Container. Upgrades sollten auch dementsprechend einfach sein: Aktuelles Image herunterladen, docker-compose down && docker-compose up -d
ausführen, und fertig.
Leider klappt das bei PostgreSQL nur bedingt: Während Minor-Versionsupgrades genau so funktionieren, wird man bei Major-Versionsupgrades lediglich mit einer Fehlermeldung begrüßt:
FATAL: database files are incompatible with server
DETAIL: The data directory was initialized by PostgreSQL version 11.15, which is not compatible with this version 13.6.
Voraussetzung
Ich gehe im Folgenden davon aus, dass man:
- Das offizielle PostgreSQL Docker Image verwendet
- Das Volume nach
/var/lib/postgresql/data
eingehängt wird - Der Benutzer
postgres
heißt (auf meinen alten Systemen verwende ich nochpgadmin
, aber Standard ist das wohl nicht mehr)
Upgrade durchführen
- Jede Anwendung, die auf die Datenbank zugreift, beenden. Wer's grafisch mag kann dafür Portainer verwenden, oder wie ich im Terminal via
docker-compose down <application name>
selektiv Anwendungen herunterfahren. PostgreSQL muss weiterhin laufen! - Dump der Datenbank erstellen: Auch das geht via Portainer, alternativ auch via
docker exec
. Der Befehl für den Dump lautetpg_dumpall -U postgres > dump.sql
. Dieser muss im Container ausgeführt werden! - Anschließend PostgreSQL stoppen
dump.sql
aus dem Volume sichern- Das Volume löschen, alternativ für den neuen Container ein anderes Volume verwenden. Hintergrund der Geschichte: PostgreSQL benötigt zwingend ein leeres Verzeichnis für den Start (auch die
dump.sql
darf sich zum Startzeitpunkt nicht im Volume befinden) - Neues Image ziehen, PostgreSQL Container starten. Auch hier wieder selektiv erst einmal nur PostgreSQL starten, noch keine anderen Anwendungen!
dump.sql
in das Volume der Datenbank kopieren/verschieben- Vorher gesicherten Daten importieren. Ich musste feststellen, dass das selbst bei kleinen Datenbanken etwas dauern kann, daher je nach Größe etwas Zeit einplanen. Analog zu Schritt 2 führt man im Container ein
psgl -U postgres < dump.sql
aus - Nachdem die Datenbank alles import hat, kann man auch die restlichen Anwendungen wieder starten
Das war's :)