Sommaire

MAJ conteneur PostgreSQL

Introduction

Pas mal d’applications utilisent des bases de données (BDD) dont certaines que j’utilise moi-même. Lorsque je le peux, j’utilise toujours une de type PostgreSQL car je pense que c’est la plus fiable.

Afin d’assurer que mes services dépendant de ces BDD fonctionnent correctement, je fige toujours la version majeure de celles-ci dans mes compositions.

En voici une illustration :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
version: "3.8"
services:
  basededonnees:
    container_name: my-basededonnees
    image: postgres:9
    environment:
      POSTGRES_DB: namek
      POSTGRES_USER: vegeta
      POSTGRES_PASSWORD: princedessaiyan
    volumes:
      - /var/lib/app/postgresql/data:/var/lib/postgresql/data

  app:
    image: editor/app:latest
    depends_on:
      - basededonnees
    environment:
      POSTGRES_DB: namek
      POSTGRES_USER: vegeta
      POSTGRES_PASSWORD: princedessaiyan

PostgreSQL fonctionne à l’ancienne, changer le tag par une version supérieur ne garantie pas la MAJ de la BDD ! De ce fait, il faut faire la main.
De plus, il faut passer chaque palier majeur un à un ! 🥹
A l’heure où j’écris ces lignes, la dernière version est la 16… J’ai donc un peu de travail.

Nous allons donc voir ici comment faire cela de la bonne manière selon les étapes suivantes :

  • Backup
  • Migration
  • Import

Backup

Avant de faire la backup, nous devons faire en sorte que notre application n’utilise pas la BDD. Le plus simple est alors de :

  • Stopper la stack
  • Éditer notre composition pour enlever notre application (en la commentant)
  • Relancer la stack (comprenant alors seulement la BDD)

Je fais donc un docker compose down et édite la composition :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
version: "3.8"
services:
  basededonnees:
    container_name: my-basededonnees
    image: postgres:9
    environment:
      POSTGRES_DB: namek
      POSTGRES_USER: vegeta
      POSTGRES_PASSWORD: princedessaiyan
    volumes:
      - /var/lib/app/postgresql/data:/var/lib/postgresql/data

#  app:
#    image: editor/app:latest
#    depends_on:
#      - basededonnees
#    environment:
#      POSTGRES_DB: namek
#      POSTGRES_USER: vegeta
#      POSTGRES_PASSWORD: princedessaiyan

Un docker compose up -d, et je retrouve ma BDD en fonction.

Je peux alors effectuer le dump de cette base :

1
docker exec -it my-basededonnees /usr/bin/pg_dumpall -U vegeta > dumpfile_v9

On obtient donc le fichier dumpfile_v9.

Migration

Il faut maintenant qu’on déploie la version supérieure de la BDD dans un volume différant de celui existant.

1
docker compose down
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: "3.8"
services:
#  basededonnees:
#    container_name: my-basededonnees
#    image: postgres:9
#    environment:
#      POSTGRES_DB: namek
#      POSTGRES_USER: vegeta
#      POSTGRES_PASSWORD: princedessaiyan
#    volumes:
#      - /var/lib/app/postgresql/data:/var/lib/postgresql/data

  basededonnees:
    image: postgres:10
    container_name: my-basededonnees
    environment:
      POSTGRES_DB: namek
      POSTGRES_USER: vegeta
      POSTGRES_PASSWORD: princedessaiyan
    volumes:
      - /var/lib/app/postgresql-10/data:/var/lib/postgresql/data

#  app:
#    image: editor/app:latest
#    depends_on:
#      - basededonnees
#    environment:
#      POSTGRES_DB: namek
#      POSTGRES_USER: vegeta
#      POSTGRES_PASSWORD: princedessaiyan
1
docker compose up -d
Volume associé
Notez bien que j’ai associé le conteneur à un autre point de montage que celui en version 9 !

Ensuite, on effectue la migration :

1
docker exec -i my-basededonnees psql -U vegeta namek < dumpfile_v9

Une bonne chose à faire après cela est de consulter la taille du volume de la BDD (du -sh /var/lib/app/postgresql-10/data) et de le comparer avec celui de la version inférieure.

Import

Maintenant que notre base est migrée, on peut l’utiliser avec notre service.

Une fois de plus, on édite le Compose en décommentant l’application :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: "3.8"
services:
#  basededonnees:
#    container_name: my-basededonnees
#    image: postgres:9
#    environment:
#      POSTGRES_DB: namek
#      POSTGRES_USER: vegeta
#      POSTGRES_PASSWORD: princedessaiyan
#    volumes:
#      - /var/lib/app/postgresql/data:/var/lib/postgresql/data

  basededonnees:
    image: postgres:10
    container_name: my-basededonnees
    environment:
      POSTGRES_DB: namek
      POSTGRES_USER: vegeta
      POSTGRES_PASSWORD: princedessaiyan
    volumes:
      - /var/lib/app/postgresql-10/data:/var/lib/postgresql/data

  app:
    image: editor/app:latest
    depends_on:
      - basededonnees
    environment:
      POSTGRES_DB: namek
      POSTGRES_USER: vegeta
      POSTGRES_PASSWORD: princedessaiyan

Lorsque j’ai UP cette stack, je l’ai faite avec un docker compose up -d && docker compose logs -f afin de voir les logs et voir si je n’avais pas d’erreur de connexion à la BDD.
Rien de tout cela, cela a fonctionné !

Il ne me reste plus qu’à appliquer cela 4 fois pour arrivée à la version 14 !

Attention aux versions
Vérifiez bien que la version vers laquelle vous upgradez est compatible avec votre application !
C’est pour cela que je m’arrête à la 14…

Une fois ce travail terminé, on peut supprimer les volumes des anciennes versions afin de faire un peu de place.
Et n’oubliez pas supprimer les images qui ne sont plus utilisées :

1
docker image prune

Problème

Ce blog n’existerait pas si c’était aussi simple !

Lorsque j’ai UP mon application avec Postgres version 14, j’ai eu les erreurs suivantes :

my-basededonnees | 2023-12-30 23:29:48.020 UTC [57] FATAL: password authentication failed for user “vegeta”
my-basededonnees | 2023-12-30 23:29:48.020 UTC [57] DETAIL: User “vegeta” does not have a valid SCRAM secret.
my-basededonnees | Connection matched pg_hba.conf line 100: “host all all all scram-sha-256”
my-basededonnees | 2023-12-30 23:29:51.079 UTC [58] FATAL: password authentication failed for user “vegeta”
my-basededonnees | 2023-12-30 23:29:51.079 UTC [58] DETAIL: User “vegeta” does not have a valid SCRAM secret.
my-basededonnees | Connection matched pg_hba.conf line 100: “host all all all scram-sha-256”
my-basededonnees | 2023-12-30 23:29:54.141 UTC [66] FATAL: password authentication failed for user “vegeta”
my-basededonnees | 2023-12-30 23:29:54.141 UTC [66] DETAIL: User “vegeta” does not have a valid SCRAM secret.
my-basededonnees | Connection matched pg_hba.conf line 100: “host all all all scram-sha-256”
my-basededonnees | 2023-12-30 23:29:57.177 UTC [67] FATAL: password authentication failed for user “vegeta”
my-basededonnees | 2023-12-30 23:29:57.177 UTC [67] DETAIL: User “vegeta” does not have a valid SCRAM secret.
my-basededonnees | Connection matched pg_hba.conf line 100: “host all all all scram-sha-256”

Depuis la version 10, le challenge d’authentification par mot de passe c’est endurci avec l’arrivée de SCRAM.
De ce que je comprends, mon application essaye donc d’utiliser cette méthode par défaut depuis la 14 (je n’ai pas eu de problème en 13).

J’ai découvert qu’en refaisant le mot de passe, ce dernier était mis dans la bonne forme.
Je me suis alors connecté à la BDD avec docker exec -i my-basededonnees psql -U vegeta namek et changé le mot de passe (pour le même) avec ALTER USER vegeta WITH PASSWORD 'princedessaiyan';

1
2
3
4
5
6
7
8
$ docker exec -it my-basededonnees psql -U vegeta namek
psql (14.10 (Debian 14.10-1.pgdg120+1))
Type "help" for help.

namek=# ALTER USER vegeta WITH PASSWORD 'princedessaiyan';
ALTER ROLE
namek=# 
\q

Une fois la stack de nouveau UP : plus de message d’erreur !
Et mon application fonctionne toujours. 😉

Conclusion

Nous avons donc vu un moyen de faire les MAJs majeures de PostgreSQL en conteneur.

Je me note aussi que la commande de dump est une bonne chose à avoir sous la main pour effectuer une backup fiable de sa BDD.