Aller au contenu

Sauvegarder et restaurer la base de la passerelle

Prendre une sauvegarde de la base, la restaurer, et vérifier l'aller-retour avant d'en avoir besoin.

La base de la passerelle porte les comptes, les condensats des clés d’accès, les plans de dépense et l’historique de consommation qui sert à facturer. Cette page décrit comment en prendre une copie, et comment la remettre en place.

Une sauvegarde qui n’a jamais été restaurée n’a pas été vérifiée. La section « Éprouver la sauvegarde » décrit l’aller-retour qui la vérifie.

Fenêtre de terminal
export DATABASE_URL="postgresql://<utilisateur>:<mot-de-passe>@<hôte>:<port>/<base>"
cd gateway-db
./sauvegarder.sh --sortie /var/sauvegardes/passerelle-$(date +%Y%m%d-%H%M%S).sql.gz

Le script affiche ensuite l’inventaire de ce qu’il a emporté, une ligne par table avec son nombre de lignes. Gardez cette sortie : c’est ce que vous comparez après une restauration.

sauvegarde écrite : /var/sauvegardes/passerelle-20260801-030000.sql.gz (412K)
Contenu sauvegardé — ce sont ces nombres qu'on doit retrouver après restauration :
table | lignes
-------------------------+--------
plans | 4
request_logs | 18742
schema_migrations | 20
users | 37

--sortie est obligatoire, et le script n’écrase pas un fichier existant. Il n’engendre pas de nom à votre place : la cadence et la rétention sont des décisions d’exploitation, que le script ne prend pas.

Il est créé en 0600, lisible par son seul propriétaire. Traitez-le comme une clé :

  • chiffrez-le avant de le déplacer ;
  • sortez-le de la machine qui porte la base ;
  • détruisez les copies devenues inutiles. Une sauvegarde antérieure à la migration 015 contient les clés de tous vos porteurs en clair.

Tout le contenu de la base : comptes et condensats de clés, plans, fournisseurs, modèles, endpoints, attributions de rôles, politiques d’autorisation, révocations, sessions, journaux d’audit, et request_logs, l’historique de consommation.

Le registre schema_migrations en fait partie. Une base restaurée sans son registre est une base que le script de migration croit vierge : il y rejouerait la chaîne entière depuis la première migration, sur des données vivantes.

Absent de la sauvegardePourquoiCe que ça vous laisse à faire
Les rôles PostgreSQL et leurs mots de passepg_dump ne copie que le contenu d’une base, pas les objets globaux du serveurrecréer les comptes de connexion sur le serveur cible
Les propriétaires et les droitsils désignent des rôles qui n’existent peut-être pas sur la destinationreposer un droit accordé à la main hors du produit
La base elle-mêmele fichier décrit un contenu, pas une existence : pas de CREATE DATABASE dedanscréer la base vide avant de restaurer
Les clés de vos fournisseursla base stocke le nom de la variable d’environnement, pas la cléredonner son environnement à la passerelle
ADMIN_API_KEYelle vit dans l’environnement de la passerelle, pas en basela redonner aussi

Une base restaurée ne fait pas une installation qui repart : il lui faut aussi son environnement.

Si le script refuse : « pg_dump 16 ne peut pas sauvegarder un serveur PostgreSQL 17 »

Section intitulée « Si le script refuse : « pg_dump 16 ne peut pas sauvegarder un serveur PostgreSQL 17 » »

pg_dump ne lit pas un serveur d’une version majeure postérieure à la sienne, et un serveur en conteneur est souvent plus récent que le client fourni par la distribution.

Installez le client de la version du serveur et placez-le en tête de PATH :

Fenêtre de terminal
export PATH="/usr/lib/postgresql/17/bin:$PATH"
pg_dump --version

Aucun fichier n’est écrit tant que ce refus s’affiche.

La restauration ne demande que psql : ni pg_restore, ni un client de la version du serveur. Un fichier pris sur un serveur 17 se restaure avec un client 16.

La base de destination doit exister et être vide :

Fenêtre de terminal
createdb -h <hôte> -U <utilisateur> proxy
export DATABASE_URL="postgresql://<utilisateur>:<mot-de-passe>@<hôte>:<port>/proxy"
cd gateway-db
./restaurer.sh /var/sauvegardes/passerelle-20260801-030000.sql.gz

Tout passe dans une transaction unique : une restauration interrompue ne laisse pas une base à moitié remplie, elle ne laisse rien.

Le script affiche à son tour l’inventaire. Comparez-le à celui de la sauvegarde : les nombres doivent être identiques, table par table.

Restaurer par-dessus une base qui contient déjà quelque chose

Section intitulée « Restaurer par-dessus une base qui contient déjà quelque chose »

Sans option, le script refuse et ne touche à rien :

erreur: la base de destination contient déjà 14 table(s).
Restaurez dans une base vide (createdb), ou relancez avec --ecraser pour remplacer
le contenu actuel. Rien n'a été touché.

--ecraser demande le remplacement. Il efface le schéma et les données de la destination avant de restaurer, dans la même transaction que la restauration :

Fenêtre de terminal
./restaurer.sh /var/sauvegardes/passerelle-20260801-030000.sql.gz --ecraser

Le geste destructeur n’est pas celui par défaut.

  1. Comparer les deux inventaires, ligne à ligne.

  2. Vérifier que le schéma est au niveau attendu. Le message attendu est celui-ci :

    Fenêtre de terminal
    ./migrate.sh
    base à jour, aucune migration à appliquer.

    Si le script annonce des migrations à appliquer, la base restaurée n’est pas au schéma attendu : arrêtez-vous et lisez Appliquer les migrations de la base avant de continuer.

  3. Redonner son environnement à la passerelle : ADMIN_API_KEY et les clés de vos fournisseurs, qui ne sont pas dans la sauvegarde.

  4. Contrôler de bout en bout : authentifier une clé connue contre la passerelle, et ouvrir la liste des comptes dans la console d’administration.

À faire avant d’en avoir besoin, et à refaire après chaque changement de version du serveur. L’essai se fait sur une base de côté ; la production n’est pas touchée.

Fenêtre de terminal
# 1. Une sauvegarde de la vraie base.
export DATABASE_URL="postgresql://<utilisateur>:<mot-de-passe>@<hôte>:<port>/proxy"
cd gateway-db
./sauvegarder.sh --sortie /tmp/essai-de-restauration.sql.gz
# 2. Une base vide, à côté, sur le même serveur.
createdb -h <hôte> -U <utilisateur> essai_de_restauration
# 3. La sauvegarde y est restaurée.
DATABASE_URL="postgresql://<utilisateur>:<mot-de-passe>@<hôte>:<port>/essai_de_restauration" \
./restaurer.sh /tmp/essai-de-restauration.sql.gz
# 4. Le schéma est complet : rien à rejouer.
DATABASE_URL="postgresql://<utilisateur>:<mot-de-passe>@<hôte>:<port>/essai_de_restauration" \
./migrate.sh
# 5. On efface la base d'essai et le fichier.
dropdb -h <hôte> -U <utilisateur> essai_de_restauration
shred -u /tmp/essai-de-restauration.sql.gz

Les deux inventaires affichés aux étapes 1 et 3 doivent coïncider, et l’étape 4 doit répondre « base à jour, aucune migration à appliquer. ».

Avant toute migration de schéma, et en particulier avant celle qui remplace les clés en clair par leur condensat (015-hacher-les-cles-api). Cette migration est irréversible : après elle, aucune requête ni aucun écran ne retrouve une clé. Une erreur à cet endroit perd les clés de tous vos porteurs, qui se régénèrent une par une.

La procédure complète des migrations, et ce que 015 fait, sont dans Appliquer les migrations de la base.

Les autres moments où la sauvegarde est due : avant une montée de version du serveur PostgreSQL, avant un déplacement de la base d’une machine à une autre, et à intervalle régulier.

  • Ils ne planifient rien : ni tâche périodique, ni rétention, ni rotation. La cadence, la durée de conservation et l’emplacement hors machine se décident dans votre exploitation ; la commande s’appelle depuis le planificateur de votre choix.
  • Ils ne chiffrent ni ne transfèrent le fichier.
  • Ils ne font pas de sauvegarde continue, donc pas de restauration à un instant choisi. Cela relève de l’archivage des journaux de transaction de PostgreSQL, qui se configure sur le serveur.