Parcours · administrateur de la plateforme
Déclarer un stockage S3, le tester, planifier les sauvegardes, lancer un passage tout de suite, puis lire son résultat et savoir retrouver un fichier.
Exemplia a ouvert un bucket chez son fournisseur S3, exemplia-sauvegardes, avec une paire de clés
dédiée. Claire Martin veut que le Hub y dépose ses sauvegardes chaque nuit. Il lui faut un compte
SUPERADMIN du Hub, et le bucket déjà créé : le Hub ne le crée pas.
Le Hub ne sauvegarde pas lui-même. Il confie le travail à un démon autonome, socle-backup, et tient
le registre : destinations, planifications, historique de chaque passage.
Rejouer tout le parcours dans le Hub
La vue d'ensemble compte les destinations, les planifications et les cibles, et donne la santé
du démon socle-backup. Le Hub l'interroge à chaque ouverture de l'écran.
healthy : le démon répond, un passage peut partir. down : un passage lancé maintenant échoue aussitôt (« daemon unreachable or returned non-JSON »).
Les fichiers produits sont dans des formats ouverts — SQL en texte, JSON, fichiers tels quels : on peut relire un seul schéma sans tout restaurer.
Action du Hub : backup_worker.get_status
Faire cette étape dans le Hub → Pour aller plus loin : backup.overview.ecran backup.overview.kpi.daemon backup.overview.familles
Une destination, c'est un bucket S3 : un endpoint, un bucket, un préfixe éventuel, une paire
de clés. Le Hub sépare les deux moitiés : l'adresse va en base, les clés vont dans Vault, au
chemin backup/destination-<nom>. Elles ne s'écrivent jamais dans l'historique.
Le nom fixe donc ce chemin : choisissez-le court, en minuscules, chiffres et tirets. Le
préfixe hub-prod/ range ce Hub dans un dossier du bucket : plusieurs Hubs peuvent le
partager sans se mélanger.
Cliquez sur Créer la destination. Le Hub écrit d'abord les clés dans Vault ; si Vault refuse, rien n'est créé. Le fournisseur S3, lui, n'est pas contacté.
⚠ La case de vérification SSL n'a aucun effet décochée : le Hub la remet à vrai. Une destination
sans vérification (un MinIO d'essai au certificat auto-signé) se crée par l'action, avec
ssl_verify à false.
Action du Hub : backup_worker.create_destination
Faire cette étape dans le Hub → Pour aller plus loin : backup.destinations.ecran backup.destinations.creer.name backup.destinations.creer.path_prefix backup.destinations.creer.ssl_verify backup.destinations.creer.valider
La destination est dans la liste. Tester lit son chemin Vault et regarde si access_key et
secret_key y sont, non vides. La colonne Dernier test passe à credentials_ok (vert), ou
en rouge : credentials_missing, vault_error.
L'écran montré ici liste les destinations d'essai d'Exemplia : votre nouvelle destination y prend une ligne de plus, avec le même bouton.
⚠ Le test ne fait aucun appel au fournisseur S3 sur le Hub 3.77.0. Une clé révoquée, un bucket supprimé ou un endpoint faux passent le test. La seule preuve qu'une destination marche, c'est un passage réussi vers elle.
Action du Hub : backup_worker.test_destination
Faire cette étape dans le Hub → Pour aller plus loin : backup.destinations.ligne.tester backup.destinations.col.test
Les cibles sont les bases que le Hub repère sur son serveur : chaque schéma PostgreSQL de la
base centrale (sauf les schémas système, public et backup), plus la TechDB du Hub. Pour un
schéma schema_<app>, la colonne App donne l'application propriétaire. La liste reste vide
tant que personne n'a cliqué sur Rescanner.
⚠ Sur le Hub 3.77.0, cette liste est un inventaire, pas un réglage : elle n'est pas transmise
au démon. Ce qui est sauvegardé se décide par les options du passage (include_postgres,
include_vault, include_techdb…). La colonne Activé n'a pas d'effet.
Action du Hub : backup_worker.refresh_targets
Faire cette étape dans le Hub → Pour aller plus loin : backup.targets.ecran backup.targets.rescanner backup.targets.col.application backup.targets.col.active
Une planification dit : « à telle heure, sauvegarde vers telle destination, et garde N jours ».
Le Hub regarde toutes les 60 secondes s'il en a une due, lance le passage, puis calcule la
prochaine échéance. Dans l'historique, le déclencheur s'appelle schedule:<nom>.
Le cron a cinq champs, à l'heure du serveur : 0 3 * * * = chaque jour à 3 h. Après chaque
passage, la rétention purge les passages plus vieux que N jours (30 par défaut).
⚠ Sur le Hub 3.77.0, le bouton ne crée rien. La liste de destinations s'appelle
destination_id dans le gabarit, alors que le Hub attend id_s3_destinations : la requête est
refusée (400) avant le contrôleur, sans message à l'écran. Créez la planification par l'action
backup_worker.create_schedule, avec name, cron_expression, id_s3_destinations,
retention_days, et les familles voulues (include_postgres, include_vault…).
⚠ Un cron illisible n'est pas refusé, et fait partir un passage à chaque tour de 60 secondes. Une minute après la création, la colonne Prochain run doit afficher une date ; si elle reste à « - », supprimez la planification.
Action du Hub : backup_worker.create_schedule
Faire cette étape dans le Hub → Pour aller plus loin : backup.schedules.ecran backup.schedules.creer.cron backup.schedules.creer.destination backup.schedules.creer.retention backup.schedules.creer.valider backup.schedules.col.prochain
Lancer le backup fait partir un passage sans attendre la nuit. Le passage est synchrone : le
Hub attend la réponse du démon avant de rendre la page, ce qui peut être long. Au retour, un
message vert « Backup OK — id_runs=…, … items, … ms », ou rouge si une partie a échoué. Le
passage apparaît aussitôt dans 5 derniers runs, déclenché par manual:portal-ui.
⚠ Ce formulaire n'envoie aucune destination : le passage reste sur la machine, dans le
dossier de transit du démon. C'est un bon contrôle du démon et des collectes, pas une
sauvegarde hors site. Pour un passage manuel vers S3 : l'action backup_worker.run_now avec
id_s3_destinations.
⚠ Décocher PostgreSQL ne le retire pas : le Hub remet la valeur à vrai.
Action du Hub : backup_worker.run_now
Faire cette étape dans le Hub → Pour aller plus loin : backup.overview.manuel.titre backup.overview.manuel.lancer backup.overview.manuel.postgres
Chaque ligne est un passage. On y lit d'un coup d'œil si ceux de la nuit sont allés au bout, et s'ils ont la taille habituelle : une sauvegarde qui fond d'un coup se voit dans la colonne Taille.
Statut : ok (tout est passé), partial (au bout, mais des éléments ont échoué),
running, failed. Un passage partial reste une sauvegarde : ce qui est ok dans son détail
est utilisable. Trigger : schedule:<nom>, manual:portal-ui, ou manual:<appelant> pour
l'action run_now.
Le cadenas 🔒 signale un passage verrouillé : la purge de rétention ne le supprime jamais.
Action du Hub : backup_worker.list_runs
Faire cette étape dans le Hub → Pour aller plus loin : backup.runs.ecran backup.overview.col.statut backup.runs.col.trigger backup.runs.col.verrou
Le haut résume le passage : statut, éléments, taille, durée, déclencheur, destination
(#N, ou « staging local » pour un passage resté sur la machine). Le tableau Items liste
chaque élément ; dans un passage partial, ce qui manque est au statut failed.
L'écran montré ici est un passage planifié de la nuit du 29 septembre, pas celui que vous venez de lancer : le vôtre a le même détail.
Restaurer. Le Hub 3.77.0 n'a ni écran ni action de restauration. Le fichier se retrouve dans
le bucket, à <préfixe de la destination><Backup ID>/<Chemin> : par exemple
hub-prod/<Backup ID>/postgres/schema_iam.sql.gz. Le Backup ID est sous le titre. Une fois le
fichier rapatrié, comparez son empreinte à la colonne SHA256 (le survol montre l'empreinte
entière) : elle prouve qu'il est intact.
Action du Hub : backup_worker.get_run
Faire cette étape dans le Hub → Pour aller plus loin : backup.run.ecran backup.run.col.chemin backup.run.col.sha256 backup.run.col.statut
ovh-prod-eu-west, ses clés rangées dans Vault ;create_schedule, dont la colonne Prochain run
affiche une date ;Le premier passage planifié vers le bucket est la vraie preuve que la destination marche : le lendemain matin, ouvrez l'historique.
credentials_ok dit seulement que les clés sont dans Vault.backup_worker.create_schedule.run_now avec id_s3_destinations.