Aller au contenu

Montée de version PostgreSQL

Quand l’image postgres change de version majeure, une mise à jour ordinaire ne suffit plus. PostgreSQL refuse de démarrer sur un répertoire de données écrit par une majeure antérieure, les données doivent donc être dumpées et rechargées. Depuis la 18, l’image possède aussi /var/lib/postgresql au lieu de data à l’intérieur, et elle refuse de démarrer sur un volume disposé à l’ancienne plutôt que de l’ignorer, si bien qu’une pile qui n’a pas été transportée échoue visiblement et ne change rien.

Fenêtre de terminal
export PGPASSWORD=$(grep -m1 '^POSTGRES_PASSWORD=' .env | cut -d= -f2-)
docker compose stop app
docker run --rm --network badlen_default -e PGPASSWORD postgres:18-alpine \
pg_dump -h db -U badlen -d badlen > badlen-dump.sql
grep -c 'PostgreSQL database dump complete' badlen-dump.sql # doit afficher 1
docker compose down
docker volume rm badlen_pgdata
docker compose up -d --wait db
docker run --rm -i --network badlen_default -e PGPASSWORD postgres:18-alpine \
psql -h db -U badlen -d badlen -v ON_ERROR_STOP=1 < badlen-dump.sql
docker compose up -d app

badlen est le POSTGRES_USER du .env, et l’application est arrêtée d’abord pour que rien n’écrive pendant le dump.

Pourquoi les deux clients sont dans la nouvelle majeure

Section intitulée « Pourquoi les deux clients sont dans la nouvelle majeure »

Les deux conteneurs clients tournent dans la nouvelle majeure exprès : pg_dump doit être au moins aussi récent que le serveur dans lequel le fichier est rechargé, et le fichier qu’il écrit emploie des méta-commandes psql qu’un psql plus ancien ne connaît pas.

--wait sur le up n’est pas une politesse. Le volume vient d’être supprimé, c’est donc le démarrage où la base crée son cluster à partir de rien, et pendant une dizaine de secondes le conteneur est levé et le serveur n’écoute pas. Sans lui, up -d rend la main dès que le conteneur existe et psql tombe sur Connection refused au seul moment où le fichier de dump est votre seule copie.

Confidentialité