Trois travaux sous un seul nom
« Mettre en place PostgreSQL » sonne comme une seule tâche. C'en est trois, et elles échouent différemment. Installer la bonne version se rate en douce en croyant presque réussir. Durcir la politique d'accès est l'étape réellement dangereuse — la seule séquence de tout cet article qui peut enfermer votre propre application dehors. Et sauvegarder est l'étape que tout le monde prétend avoir faite et que presque personne n'a testée. Les traiter comme un seul travail flou, c'est finir avec une base sur une version qu'on n'a pas choisie, ouverte sur un réseau qu'on n'avait pas prévu, avec une sauvegarde que personne n'a jamais restaurée.
La thèse, donc : le risque dans une base n'est pas l'installation, c'est la donnée — chaque étape se juge donc à sa capacité à perdre ou exposer des données, pas à la bonne installation du paquet. Ce seul prisme réordonne tout le travail.
Avant tout : y a-t-il déjà un cluster ici ?
C'est la reconnaissance qui compte plus que toute autre dans cet article, parce que le mode de défaillance est irréversible. Si un cluster PostgreSQL existe déjà — une arborescence /etc/postgresql sur Debian, un répertoire de données /var/lib/pgsql sur RHEL — alors relancer un installeur qui le réinitialise ne met pas votre base à jour. Il la remplace par une base vide. Il n'y a pas d'annulation, et aucune excuse assez grande.
- Postgres est-il présent, et dans quelle version ?
command -v psql && psql --version. Un écart de version majeure décide si vous installez ou si vous migrez — deux travaux très différents. - Le service tourne-t-il, et le 5432 est-il pris ?
systemctl is-active postgresqletss -tlnH 'sport = :5432'. Un cluster vivant sur le port est le signal le plus fort possible pour s'arrêter et lire avant d'agir. - Un répertoire de données existe-t-il déjà ? Si oui, les seules opérations sûres sont en lecture seule : vérifier la version, rapporter l'état, et refuser de réinitialiser. Ne jamais réinstaller par-dessus des données.
Disons-le franchement, parce que c'est celle qui met fin aux carrières : ne jamais réinitialiser un cluster qui contient déjà des données. Si Postgres est déjà là, le bon comportement est de vérifier et de rapporter, pas d'installer par-dessus. La seule façon de savoir si cette condition tient est de regarder d'abord — et c'est exactement pour cela que la recette commence par la reconnaissance et refuse de toucher un répertoire qu'elle ne s'attendait pas à trouver.
1. Installer une version choisie, depuis une source de confiance
Le piège de l'installation de Postgres, c'est la version obtenue par défaut. Le paquet fourni par une distribution peut avoir une version majeure ou deux de retard, et une version majeure n'est pas un détail — elle gouverne le format sur disque, et on ne rétrograde pas à la légère ensuite. La voie honnête est le dépôt du projet PostgreSQL lui-même (PGDG) : ajouter le dépôt signé, puis installer la version majeure exacte voulue, postgresql-16 ou celle que vous avez épinglée.
Les deux faits qui prouvent l'étape, pas le code de retour :
- le fichier de dépôt existe là où il doit — une source qu'on peut nommer est une chaîne d'approvisionnement sur laquelle on peut raisonner ;
psql --versionrapporte la version majeure demandée, pas celle que la distribution a livrée par hasard. Vérifier le numéro, c'est tout l'intérêt de l'épingler.
Puis systemctl enable --now postgresql, et prouvez que le serveur répond vraiment plutôt que d'être seulement « active » : sudo -u postgres psql -tAc 'select 1' qui rend 1, c'est une base qui accepte une requête, une affirmation plus forte qu'une unité verte.
2. Durcir la politique d'accès — la seule étape destructrice
Une installation Postgres par défaut n'est pas grande ouverte sur Internet, mais ses règles d'accès sont plus lâches qu'une base de production ne le veut, et sa méthode d'authentification n'est pas forcément la plus solide. Durcir signifie trois choses : contraindre qui peut se connecter et d'où dans pg_hba.conf, forcer scram-sha-256 pour que les mots de passe ne soient jamais stockés ni vérifiés sous une forme plus faible, et activer SSL pour les connexions qui traversent un réseau.
C'est la seule étape de l'article réellement destructrice, et elle mérite honnêtement le label : ratez le pg_hba.conf et vous coupez l'application même que la base existe pour servir. Une règle trop serrée n'échoue pas au reload — elle échoue à la prochaine connexion ouverte par votre app, quelques secondes ou quelques minutes plus tard, et la panne ressemble à la faute de l'application. La discipline autour n'est donc pas optionnelle :
- Sauvegardez la config d'abord. Copiez
pg_hba.confetpostgresql.confen.bakavant de modifier. Un rollback qui restaure les deux fichiers et recharge, c'est la différence entre une reprise de cinq secondes et un incident. - Vérifiez les connexions actives avant de resserrer. Sachez qui est connecté et d'où, pour qu'une nouvelle règle ne coupe pas une session en plein vol.
- Rechargez, ne redémarrez pas. Un
systemctl reload postgresqlapplique la nouvelle politique aux nouvelles connexions sans faire tomber le cluster ; vérifiez avecshow password_encryptionqui rendscram-sha-256, et l'unité toujoursactive.
Parce que cette étape est destructrice, c'est celle qui mérite un snapshot au préalable et une approbation délibérée, les yeux ouverts — pas un clic réflexe. Tout ce qui précède a rétréci le risque de la machine ; celle-ci touche au risque de la donnée.
3. Une sauvegarde n'est réelle qu'une fois qu'elle a produit un fichier
La sauvegarde la plus répandue au monde est celle qui a été configurée, a rapporté un succès, et n'a jamais été restaurée. Un pg_dump planifié est réellement peu risqué côté données — il ne fait que lire — c'est exactement pourquoi on le met en place et on l'oublie. La défaillance n'est jamais la commande de dump ; c'est le credential expiré, le disque plein, la rétention qui a supprimé la seule bonne copie, le cron qui a cessé de se déclencher après un redémarrage.
La sauvegarde ne vaut donc que sa preuve :
- un script qui dumpe la base, la compresse, et impose une fenêtre de rétention pour que les vieilles copies soient purgées mais que les récentes survivent ;
- un timer systemd à la cadence choisie — horaire, quotidien, hebdomadaire — et
systemctl list-timersqui le montre planifié, parce qu'un timer qui existe est une sauvegarde qui continuera d'avoir lieu ; - un dump que vous avez réellement produit et inspecté : lancez-le une fois à la main et confirmez qu'un vrai
.gzatterrit sur le disque avec une taille plausible. Un fichier de zéro octet est une stratégie de sauvegarde qui vous lâchera au pire moment.
Gardez les credentials hors de l'historique shell — un ~/.pgpass en mode 600, pas un mot de passe sur la ligne de commande — et, pour tout ce qui dépasse le projet de loisir, envisagez un outil conçu pour la tâche. Un système de sauvegarde dédié avec un dépôt hors-machine transforme « on a un dump quelque part » en « on a des points de restauration vérifiés », la seule affirmation de sauvegarde qui vaille.
Ce que cela ne fait pas
Rien de tout cela ne rend la base hautement disponible. Un nœud unique avec de bonnes sauvegardes reste un nœud unique ; si la machine meurt, vous restaurez, vous ne basculez pas, et la restauration prend le temps qu'elle prend. Durcir la politique d'accès ne dit rien de la sûreté des requêtes que votre application envoie — l'injection SQL vit dans l'app, pas dans pg_hba.conf. Et une sauvegarde ne remplace ni le tuning, ni le pooling de connexions, ni le monitoring qui vous dit que le disque se remplit avant que le dump ne le fasse. Cet article rétrécit trois risques précis ; il ne fait pas tourner Postgres tout seul.
La vérification qui le prouve
Dans l'ordre, avant de considérer que c'est fait : psql -tAc 'select 1' pour un serveur vivant ; show server_version pour la version épinglée ; show password_encryption et une lecture de pg_hba.conf pour la politique d'accès ; le timer de renouvellement ou de sauvegarde listé et activé ; et — celle qu'on saute — une vraie restauration du dernier dump dans une base jetable, parce qu'une sauvegarde qu'on n'a pas restaurée est une hypothèse, pas une sauvegarde.
Ce que Servor apporte là-dedans
Servor livre chacun de ces travaux comme une recette — installer, durcir, sauvegarder — et la forme d'une recette est ce qui garde une opération sur des données honnête. Une recette n'est pas un script figé tiré à l'aveugle : elle commence par la reconnaissance, si bien que l'installation refuse de réinitialiser un cluster trouvé, et l'étape de durcissement lit l'emplacement réel de pg_hba.conf au lieu de le deviner. Chaque étape porte sa propre vérification vérifiable par une machine — le select 1, le scram-sha-256, le .gz sur disque — si bien que le run prouve ce qu'il a fait. Le playbook est idempotent : un Postgres existant est vérifié et rapporté, jamais installé par-dessus.
La recette de durcissement est marquée destructive exprès. Elle demande un snapshot au préalable, une seconde approbation délibérée, et elle porte un rollback qui restaure la config depuis la sauvegarde — parce que l'auteur de la recette, pas le modèle, a décidé que cette étape touche à l'accès et doit être réversible. Au-delà, Servor ne prend aucun snapshot de vos données et ne restaure rien automatiquement : une opération destructrice reste destructrice, et la rattraper, c'est le rôle de vos sauvegardes. On préfère l'écrire que vous laisser supposer un filet de sécurité qui n'existe pas.
Chaque commande passe toujours par la même boucle que le copilote : signée dans votre navigateur avec une clé dérivée de votre clé de vault, relayée verbatim, vérifiée sur la machine par l'agent avant de s'exécuter. La liste de commandes interdites — appliquée côté plan de contrôle et de nouveau côté agent — refuse le vraiment catastrophique quoi que vous approuviez. Comment fonctionne cette discipline approuver-signer-vérifier fait l'objet de l'article Plan-Execute-Verify ; comment Servor opère sur vos serveurs sans jamais voir vos secrets est traité dans l'article sur le zero-knowledge.