<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ZINSOU Trinité</title>
    <description>The latest articles on DEV Community by ZINSOU Trinité (@trinitezinsou).</description>
    <link>https://dev.to/trinitezinsou</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F870896%2F7b8df902-3aff-4803-a6da-111922da6d9e.png</url>
      <title>DEV Community: ZINSOU Trinité</title>
      <link>https://dev.to/trinitezinsou</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/trinitezinsou"/>
    <language>en</language>
    <item>
      <title>Maîtriser la gestion des branches avec Git</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Fri, 17 Oct 2025 21:43:33 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/maitriser-la-gestion-des-branches-avec-git-3ikh</link>
      <guid>https://dev.to/trinitezinsou/maitriser-la-gestion-des-branches-avec-git-3ikh</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine ton équipe de devs comme une bande de super-héros. Chacun a ses pouvoirs, chacun travaille sur une mission différente. Mais si tout le monde se met à lancer des lasers sur sa cible sans coordination, la ville finira en ruines au lieu d’être sauvée.&lt;/p&gt;

&lt;p&gt;C’est là que &lt;strong&gt;Git&lt;/strong&gt; entre en jeu. Puissant, il offre aux développeurs la liberté de créer des espaces de travail isolés, d’expérimenter et de collaborer sans se marcher dessus. Mais cette liberté peut vite tourner au chaos : sans stratégie claire pour gérer les branches, les équipes se retrouvent souvent avec des historiques brouillons, des conflits de fusion interminables et des flux de déploiement incertains.&lt;/p&gt;

&lt;p&gt;Une &lt;strong&gt;bonne stratégie de gestion des branches&lt;/strong&gt; ne se contente pas d’organiser le code : elle influence la manière dont ton équipe collabore, livre des fonctionnalités, corrige des bugs et déploie ses produits.&lt;/p&gt;

&lt;p&gt;Dans cet article, nous allons explorer &lt;strong&gt;quelques stratégies de gestion des branches Git les plus populaires&lt;/strong&gt;, leurs avantages et leurs inconvénients, afin de t’aider à trouver &lt;strong&gt;celle qui correspond le mieux à ton équipe&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌱 Qu’est-ce qu’une branche Git ?
&lt;/h2&gt;

&lt;p&gt;Imagine les branches Git comme des &lt;strong&gt;lignes temporelles alternatives&lt;/strong&gt; dans un film Marvel.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dans une ligne temporelle, tu construis une page de connexion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dans une autre, tu corriges un vilain bug en production.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Et dans une troisième, tu expérimentes un mode sombre (parce que… pourquoi pas 😎).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les branches te permettent d’explorer &lt;strong&gt;tous ces univers parallèles&lt;/strong&gt; sans abîmer l’histoire principale(ici ton projet 😉).&lt;/p&gt;

&lt;p&gt;Techniquement, une branche Git est simplement un &lt;strong&gt;pointeur vers un commit&lt;/strong&gt; : une référence légère qui te permet de travailler sur des changements sans impacter directement la base de code principale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pourquoi utiliser des branches ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Pour &lt;strong&gt;isoler les fonctionnalités&lt;/strong&gt; tant qu’elles ne sont pas prêtes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pour &lt;strong&gt;corriger des bugs&lt;/strong&gt; sans perturber le développement en cours.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pour &lt;strong&gt;préparer des releases&lt;/strong&gt; de manière contrôlée.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pense aux branches comme à des &lt;strong&gt;lignes temporelles parallèles&lt;/strong&gt; dans ton projet.&lt;br&gt;&lt;br&gt;
Un bon modèle de branches les garde &lt;strong&gt;propres et maîtrisées&lt;/strong&gt;, et t’évite surtout un cataclysme interdimensionnel, un effet papillon à l’échelle du multivers (merci Marvel 😉).&lt;/p&gt;

&lt;h3&gt;
  
  
  🪵 Les 6 principaux types de branches
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type de branche&lt;/th&gt;
&lt;th&gt;Rôle principal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;main / master&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pour préparer les versions en production, de manière contrôlée.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dev / develop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Branche d’intégration des nouvelles fonctionnalités et correctifs. Contient l’état le plus récent du développement (pas forcément stable).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;feature&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pour les nouvelles fonctionnalités ou améliorations. Créée à partir de &lt;code&gt;dev&lt;/code&gt;, fusionnée ensuite dans &lt;code&gt;dev&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;release&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pour finaliser une version. Créée à partir de &lt;code&gt;dev&lt;/code&gt;, fusionnée après dans &lt;code&gt;main&lt;/code&gt; et &lt;code&gt;dev&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;hotfix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pour les correctifs urgents en production. Créée à partir de &lt;code&gt;main&lt;/code&gt;, fusionnée après dans &lt;code&gt;main&lt;/code&gt; et &lt;code&gt;dev&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;fix (optionnelle)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pour les bugs mineurs non critiques. Créée à partir de &lt;code&gt;dev&lt;/code&gt; (ou d’une &lt;code&gt;release&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🏷️ Nommer ses branches Git
&lt;/h2&gt;

&lt;p&gt;Chaque équipe est libre de définir ses propres règles de nommage des branches, ce qui compte vraiment, c’est &lt;strong&gt;la cohérence&lt;/strong&gt;. Une convention très répandue consiste à &lt;strong&gt;préfixer les branches selon leur type&lt;/strong&gt; (&lt;code&gt;feature/&lt;/code&gt;, &lt;code&gt;release/&lt;/code&gt;, &lt;code&gt;hotfix/&lt;/code&gt;, etc.) et à utiliser des &lt;strong&gt;noms courts, descriptifs&lt;/strong&gt;, en &lt;strong&gt;minuscules&lt;/strong&gt; et &lt;strong&gt;séparés par des tirets&lt;/strong&gt;. Par exemple : &lt;code&gt;feature/login-page&lt;/code&gt; , &lt;code&gt;release/1.0.0&lt;/code&gt; ,&lt;code&gt;hotfix/1.0.1&lt;/code&gt; . Cette approche garde ton dépôt &lt;strong&gt;propre et lisible&lt;/strong&gt;, et permet de &lt;strong&gt;comprendre instantanément l’objectif&lt;/strong&gt; de chaque branche.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Les stratégies majeures
&lt;/h2&gt;

&lt;p&gt;Chaque dépôt Git démarre avec une seule branche : &lt;strong&gt;main&lt;/strong&gt; (ou &lt;strong&gt;master&lt;/strong&gt;, selon les cas). C’est &lt;strong&gt;l’épine dorsale du projet&lt;/strong&gt;; tout repose dessus. Imaginons donc une équipe de développement travaillant sur plusieurs fonctionnalités principales, de &lt;code&gt;feat1&lt;/code&gt; à &lt;code&gt;featN&lt;/code&gt;, à partir d’un même dépôt avec sa branche principale. Nous verrons ensuite une liste de quelques-unes des stratégies les plus utilisées dans l'industrie.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Feature Branching
&lt;/h3&gt;

&lt;p&gt;Avec elle, chaque fonctionnalité, changement ou correctif possède &lt;strong&gt;sa propre branche&lt;/strong&gt;, créée à partir de la branche principale (&lt;code&gt;main&lt;/code&gt;). Une fois le développement terminé, la branche est fusionnée dans &lt;code&gt;main&lt;/code&gt;, puis &lt;strong&gt;supprimée&lt;/strong&gt; pour garder le dépôt propre.&lt;/p&gt;

&lt;p&gt;Cette approche favorise &lt;strong&gt;l’isolation du développement&lt;/strong&gt;; chaque développeur peut travailler sur ses fonctionnalités sans interférer avec le code principal. Mais attention, cela peut entraîner des &lt;strong&gt;conflits Git&lt;/strong&gt; lors des fusions sur &lt;code&gt;main&lt;/code&gt;,&lt;br&gt;&lt;br&gt;
surtout si les branches ont subies de longues modifications. La clé de cette méthode, c’est &lt;strong&gt;la discipline&lt;/strong&gt; : mettre régulièrement à jour ses branches avec &lt;code&gt;main&lt;/code&gt; pour éviter les mauvaises surprises. Le schéma ci-dessous illustre bien son fonctionnement :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec4jmw66l5qn7ij2kowa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec4jmw66l5qn7ij2kowa.png" alt="feature branching" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Les développeurs commencent par &lt;strong&gt;créer leurs branches de fonctionnalités&lt;/strong&gt; à partir de &lt;code&gt;main&lt;/code&gt; (&lt;strong&gt;1&lt;/strong&gt;). Le dev travaillant sur &lt;code&gt;feat1&lt;/code&gt; effectue plusieurs commits avant de &lt;strong&gt;fusionner sa branche&lt;/strong&gt; dans &lt;code&gt;main&lt;/code&gt; à l’étape &lt;strong&gt;2&lt;/strong&gt;. À ce moment-là, la branche &lt;code&gt;feat1&lt;/code&gt; est &lt;strong&gt;supprimée&lt;/strong&gt; (représentée par une ligne en pointillés). Puis, au &lt;strong&gt;point 3&lt;/strong&gt;, le dev travaillant sur &lt;code&gt;feat2&lt;/code&gt; termine ses modifications en &lt;strong&gt;récupérant les derniers changements de&lt;/strong&gt; &lt;code&gt;main&lt;/code&gt; pour se synchroniser. Cette étape permet d’éviter les conflits lors de la fusion au &lt;strong&gt;point 4&lt;/strong&gt;, après quoi cette branche est également supprimée.&lt;/p&gt;

&lt;p&gt;En résumé, cette stratégie constitue &lt;strong&gt;la base de la plupart des autres stratégies&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Git Flow
&lt;/h3&gt;

&lt;p&gt;Avec &lt;strong&gt;Git Flow&lt;/strong&gt;, on maintient &lt;strong&gt;deux branches permanentes&lt;/strong&gt; : une pour la &lt;strong&gt;production&lt;/strong&gt; et une pour la &lt;strong&gt;pré-production&lt;/strong&gt;, généralement nommées &lt;code&gt;main&lt;/code&gt; et &lt;code&gt;dev&lt;/code&gt;. À cela peuvent s’ajouter d’autres branches selon le contexte, comme les branches &lt;code&gt;feature/&lt;/code&gt;, &lt;code&gt;fix/&lt;/code&gt; ou &lt;code&gt;hotfix/&lt;/code&gt;. Ici, avoir &lt;strong&gt;de bonnes conventions de nommage&lt;/strong&gt; joue un rôle essentiel pour garder le projet &lt;strong&gt;clair, cohérent et bien organisé&lt;/strong&gt;. Le schéma ci-dessous illustre parfaitement le fonctionnement du &lt;strong&gt;Git Flow&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd8kmxd1elvg3ylwzyd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd8kmxd1elvg3ylwzyd2.png" alt="Git Flow" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Les développeurs créent leurs &lt;strong&gt;branches de fonctionnalités&lt;/strong&gt; à partir de &lt;code&gt;dev&lt;/code&gt; pour construire de nouvelles choses géniales, puis les fusionnent une fois qu’elles sont prêtes. Quand le projet approche de la mise en production, une &lt;strong&gt;branche de release&lt;/strong&gt; est créée pour les &lt;strong&gt;dernières retouches et tests&lt;/strong&gt; avant le déploiement final. Une fois validée, cette branche est &lt;strong&gt;fusionnée à la fois dans&lt;/strong&gt; &lt;code&gt;main&lt;/code&gt; et dans &lt;code&gt;dev&lt;/code&gt;. Mais que se passe t’il si un &lt;strong&gt;bug se glisse en production&lt;/strong&gt; ?&lt;br&gt;&lt;br&gt;
C’est là que les &lt;strong&gt;branches&lt;/strong&gt; &lt;code&gt;hotfix&lt;/code&gt; entrent en scène, comme des &lt;strong&gt;pompiers du code&lt;/strong&gt; 🧯: elles sont créées directement à partir de la version de &lt;code&gt;main&lt;/code&gt; affectée en production, corrigent le problème, puis la correction est ensuite sychronisée dans &lt;code&gt;main&lt;/code&gt; et &lt;code&gt;dev&lt;/code&gt;. Ce flux de travail est conçu pour un &lt;strong&gt;développement structuré et orienté release&lt;/strong&gt;, pas pour du déploiement immédiat. La conséquence de tout ceci c’est une production &lt;strong&gt;stable&lt;/strong&gt;, des versions &lt;strong&gt;propres&lt;/strong&gt;, et une équipe qui sait &lt;strong&gt;exactement où travailler sans se marcher dessus&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. GitHub Flow
&lt;/h3&gt;

&lt;p&gt;Si &lt;strong&gt;Git Flow&lt;/strong&gt; te semble un peu lourd, avec toutes ses demandes de fusion à gérer, rencontre son &lt;strong&gt;cousin plus léger : GitHub Flow&lt;/strong&gt;. Cette stratégie, lancée par &lt;strong&gt;GitHub&lt;/strong&gt;, est conçue pour les équipes qui veulent &lt;strong&gt;livrer vite et souvent&lt;/strong&gt;, c’est un workflow &lt;strong&gt;orienté déploiement continu&lt;/strong&gt;. Contrairement à Git Flow :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;il n’y a &lt;strong&gt;pas de branche&lt;/strong&gt; &lt;code&gt;develop&lt;/code&gt;,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pas de &lt;strong&gt;branches&lt;/strong&gt; &lt;code&gt;release&lt;/code&gt; longue durée,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;seulement &lt;code&gt;main&lt;/code&gt; (ou &lt;code&gt;master&lt;/code&gt;) et des &lt;strong&gt;branches de fonctionnalités courtes&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avec GitHub Flow : tout ce qui est dans &lt;code&gt;main&lt;/code&gt; est &lt;strong&gt;déployable&lt;/strong&gt;, pour développer une fonctionnalité, crée une &lt;strong&gt;branche de feature&lt;/strong&gt;, fais tes changements, créé une &lt;strong&gt;pull/merge request&lt;/strong&gt;, fusionne la branche, et &lt;strong&gt;tes changements sont prêts à être déployés&lt;/strong&gt;. Quelques problèmes mineurs peuvent apparaître, mais ils peuvent être &lt;strong&gt;corrigés et redéployés immédiatement&lt;/strong&gt; : dans ce workflow, un &lt;strong&gt;hotfix&lt;/strong&gt; n’est pas différent d’une &lt;strong&gt;petite fonctionnalité&lt;/strong&gt;. Tu codes, tu merges, et tu livres directement depuis &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funpxswlegvgdq1c3rmg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funpxswlegvgdq1c3rmg0.png" alt="Github Flow" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. GitLab Flow
&lt;/h3&gt;

&lt;p&gt;Ce workflow &lt;strong&gt;priorise les environnements de staging&lt;/strong&gt;. Si Git Flow te paraît &lt;strong&gt;trop lourd&lt;/strong&gt; et GitHub Flow &lt;strong&gt;trop léger&lt;/strong&gt;, alors &lt;strong&gt;GitLab Flow&lt;/strong&gt; est un &lt;strong&gt;juste milieu&lt;/strong&gt;. Il combine la &lt;strong&gt;simplicité du Feature Branching&lt;/strong&gt; avec la &lt;strong&gt;flexibilité du déploiement basé sur les environnements&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzmjix98w1q90gandr7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzmjix98w1q90gandr7f.png" alt="Gitlab Flow" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Les développeurs créent toujours des &lt;strong&gt;branches de fonctionnalités&lt;/strong&gt; à partir de &lt;code&gt;main&lt;/code&gt; (parfois à partir de &lt;code&gt;develop&lt;/code&gt; si cette branche est utilisée). Au lieu de &lt;strong&gt;plusieurs branches longue durée&lt;/strong&gt; comme dans Git Flow, GitLab Flow met l’accent sur les &lt;strong&gt;environnements&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;main&lt;/strong&gt; (production)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pré-production / staging&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;development / dev&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chaque branche d’environnement &lt;strong&gt;reflète une étape réelle de déploiement&lt;/strong&gt;. Les fonctionnalités sont &lt;strong&gt;fusionnées dans la branche appropriée&lt;/strong&gt; selon l’endroit où elles doivent être déployées.&lt;/p&gt;

&lt;p&gt;Le code circule ainsi : &lt;code&gt;main&lt;/code&gt; → &lt;code&gt;pré-production&lt;/code&gt; → &lt;code&gt;production&lt;/code&gt; .&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Release Branching
&lt;/h3&gt;

&lt;p&gt;Le &lt;strong&gt;Release Branching&lt;/strong&gt; est une approche &lt;strong&gt;structurée&lt;/strong&gt; utilisée dans les processus de développement logiciel. Lorsque le projet approche d’une &lt;strong&gt;nouvelle version&lt;/strong&gt;, une &lt;strong&gt;branche de release dédiée&lt;/strong&gt; est créée à partir de &lt;code&gt;main&lt;/code&gt;(parfois à partir de &lt;code&gt;develop&lt;/code&gt;). Cette branche sert de &lt;strong&gt;zone de sécurité&lt;/strong&gt; : les équipes peuvent y appliquer les &lt;strong&gt;dernières retouches&lt;/strong&gt;, corriger les &lt;strong&gt;bugs restants&lt;/strong&gt;, stabiliser la &lt;strong&gt;base de code&lt;/strong&gt;, tout cela &lt;strong&gt;sans bloquer ni perturber le développement des fonctionnalités en cours&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1n69lbx667w3i9katy4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1n69lbx667w3i9katy4d.png" alt="Release branching" width="525" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contrairement aux &lt;strong&gt;branches de fonctionnalités&lt;/strong&gt;, qui se concentrent sur le développement de fonctionnalités spécifiques, ou aux &lt;strong&gt;branches hotfix&lt;/strong&gt;, qui servent à corriger des problèmes urgents en production, les &lt;strong&gt;branches de release&lt;/strong&gt; ont une &lt;strong&gt;mission unique&lt;/strong&gt;. Elles &lt;strong&gt;regroupent tout le travail prévu pour la prochaine version&lt;/strong&gt; et offrent un &lt;strong&gt;environnement contrôlé&lt;/strong&gt; pour peaufiner et préparer le produit au déploiement. En d’autres termes, elles servent de &lt;strong&gt;pont entre le développement actif et la production&lt;/strong&gt;, garantissant que la version soit &lt;strong&gt;cohérente, stable et prête à être mise en ligne&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Trunk-Based Development
&lt;/h3&gt;

&lt;p&gt;Si &lt;strong&gt;Git Flow&lt;/strong&gt; est structuré et que &lt;strong&gt;GitHub Flow&lt;/strong&gt; est léger, alors &lt;strong&gt;Trunk-Based Development (TBD)&lt;/strong&gt; est &lt;strong&gt;l’extrême minimaliste&lt;/strong&gt; 🪶. Le principe est simple : &lt;strong&gt;tout le monde travaille sur une seule branche&lt;/strong&gt;, le &lt;strong&gt;tronc&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
(généralement &lt;code&gt;main&lt;/code&gt; ou &lt;code&gt;master&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasraq7fohrat4wkpim1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasraq7fohrat4wkpim1h.png" alt="Trunk-Based" width="676" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dans le &lt;strong&gt;Trunk-Based Development&lt;/strong&gt;, les développeurs travaillent généralement sur des &lt;strong&gt;branches de courte durée&lt;/strong&gt;, contenant seulement quelques commits.&lt;br&gt;&lt;br&gt;
Contrairement aux stratégies qui utilisent des &lt;strong&gt;branches de fonctionnalités longue durée&lt;/strong&gt;, cette approche permet de &lt;strong&gt;livrer du code rapidement et régulièrement&lt;/strong&gt;. Elle devient particulièrement &lt;strong&gt;précieuse lorsque la base de code et l’équipe s’agrandissent&lt;/strong&gt;, aidant à maintenir un &lt;strong&gt;flux constant de releases en production&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧭 Choisir la bonne stratégie de branches Git
&lt;/h2&gt;

&lt;p&gt;Avec Git comme &lt;strong&gt;standard de facto&lt;/strong&gt;, les équipes sont confrontées à une question cruciale : &lt;strong&gt;quelle stratégie de branches soutient le mieux leur workflow, leur architecture et leur cadence de releases ?&lt;/strong&gt; Que vous développiez un &lt;strong&gt;monolithe&lt;/strong&gt; ou orchestriez des &lt;strong&gt;microservices&lt;/strong&gt;, travailliez seul ou à plusieurs dizaines de développeurs, le &lt;strong&gt;modèle de branches que vous choisissez&lt;/strong&gt; peut &lt;strong&gt;accélérer ou freiner&lt;/strong&gt; vos progrès. Ce guide compare les stratégies présentées ci-dessus pour vous aider à &lt;strong&gt;trouver celle qui correspond le mieux à votre workflow&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stratégie&lt;/th&gt;
&lt;th&gt;Adaptation à l’architecture&lt;/th&gt;
&lt;th&gt;Taille de l’équipe&lt;/th&gt;
&lt;th&gt;Style de déploiement&lt;/th&gt;
&lt;th&gt;Idéal pour&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feature Branching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Monolithe&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ Microservices&lt;/td&gt;
&lt;td&gt;👥 Petite à grande (3–50+)&lt;/td&gt;
&lt;td&gt;🌀 Modéré à rapide&lt;/td&gt;
&lt;td&gt;- Travail isolé sur les fonctionnalités&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Développement parallèle&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Culture de revue de code&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Git Flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Monolithe&lt;/td&gt;
&lt;td&gt;👥 Moyenne à grande (10–100)&lt;/td&gt;
&lt;td&gt;🧊 Releases lentes et planifiées&lt;/td&gt;
&lt;td&gt;- Applications d’entreprise traditionnelles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Environnements QA/staging&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Gestion des hotfix&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Microservices&lt;/td&gt;
&lt;td&gt;👥 Petite à moyenne (3–30)&lt;/td&gt;
&lt;td&gt;⚡ Livraison continue&lt;/td&gt;
&lt;td&gt;- Produits SaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Iteration rapide&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Workflows PR GitHub&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitLab Flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Microservices&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ Hybride&lt;/td&gt;
&lt;td&gt;👥 Moyenne à grande (10–100)&lt;/td&gt;
&lt;td&gt;🌀 Flexible (CI/CD + staging)&lt;/td&gt;
&lt;td&gt;- Déploiements basés sur l’environnement&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Pipelines GitLab CI/CD&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Modèles de release complexes&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release Branching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Monolithe&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ Hybride&lt;/td&gt;
&lt;td&gt;👥 Moyenne à grande (10–100)&lt;/td&gt;
&lt;td&gt;🧊 Releases versionnées&lt;/td&gt;
&lt;td&gt;- Support long terme&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Développement parallèle de fonctionnalités + maintenance&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Secteurs réglementés&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Trunk-Based Development&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Microservices&lt;/td&gt;
&lt;td&gt;👥 Petite à moyenne (3–30)&lt;/td&gt;
&lt;td&gt;⚡ Intégration continue&lt;/td&gt;
&lt;td&gt;- Équipes à haute vélocité&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Culture DevOps&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;- Utilisation de feature flags&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;Au final, &lt;strong&gt;aucune stratégie de branches ne règne sur toutes les autres&lt;/strong&gt;, et c’est toute la beauté de Git.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature Branching&lt;/strong&gt; vous offre &lt;strong&gt;l’isolation&lt;/strong&gt;, &lt;strong&gt;Git Flow&lt;/strong&gt; apporte &lt;strong&gt;l’ordre&lt;/strong&gt;, &lt;strong&gt;GitHub Flow&lt;/strong&gt; garde les choses &lt;strong&gt;légères&lt;/strong&gt;, &lt;strong&gt;GitLab Flow&lt;/strong&gt; ajoute un &lt;strong&gt;contrôle des environnements&lt;/strong&gt;, &lt;strong&gt;Release Branching&lt;/strong&gt; assure la &lt;strong&gt;stabilité&lt;/strong&gt;, et &lt;strong&gt;Trunk-Based Development&lt;/strong&gt; favorise la &lt;strong&gt;vélocité&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;La &lt;strong&gt;meilleure stratégie&lt;/strong&gt; est celle qui correspond à &lt;strong&gt;la culture de votre équipe&lt;/strong&gt;, à &lt;strong&gt;votre rythme de release&lt;/strong&gt; et à &lt;strong&gt;la maturité de vos outils&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Si vos développeurs aiment &lt;strong&gt;expérimenter et livrer rapidement&lt;/strong&gt;, optez pour &lt;strong&gt;une approche légère&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Si vous gérez des &lt;strong&gt;systèmes critiques en production&lt;/strong&gt;, la &lt;strong&gt;structure est votre alliée&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;strong&gt;Rappelez-vous :&lt;/strong&gt; les stratégies de branches sont des &lt;strong&gt;outils&lt;/strong&gt;, pas des règles.&lt;br&gt;&lt;br&gt;
Vous pouvez même &lt;strong&gt;les mélanger et les adapter&lt;/strong&gt; : ce qui compte vraiment, c’est la &lt;strong&gt;cohérence, la collaboration et la livraison de code génial&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Si vous souhaitez aller plus loin, consultez ces excellentes ressources :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.gitlab.co.jp/ee/topics/gitlab_flow.html" rel="noopener noreferrer"&gt;https://docs.gitlab.co.jp/ee/topics/gitlab_flow.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://githubflow.github.io" rel="noopener noreferrer"&gt;https://githubflow.github.io&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.atlassian.com/fr/git/tutorials/comparing-workflows" rel="noopener noreferrer"&gt;https://www.atlassian.com/fr/git/tutorials/comparing-workflows&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.harness.io/blog/the-basics-of-release-branching" rel="noopener noreferrer"&gt;https://www.harness.io/blog/the-basics-of-release-branching&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://trunkbaseddevelopment.com" rel="noopener noreferrer"&gt;https://trunkbaseddevelopment.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>programming</category>
      <category>development</category>
      <category>versioning</category>
    </item>
    <item>
      <title>Mastering Git Branching Strategies: Finding the Right Fit for Your Team</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Fri, 17 Oct 2025 21:36:48 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/mastering-git-branching-strategies-finding-the-right-fit-for-your-team-4p2n</link>
      <guid>https://dev.to/trinitezinsou/mastering-git-branching-strategies-finding-the-right-fit-for-your-team-4p2n</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine your dev team as a group of superheroes. Everyone’s got powers, everyone’s working on different missions, but if you all start blasting lasers at the same target with no coordination, you’ll end up destroying the city instead of saving it. That’s where git comes in, it is powerful and gives developers the freedom to create isolated workspaces, experiment, and collaborate without stepping on each other’s toes. But with this freedom comes chaos and without a &lt;strong&gt;branching strategy&lt;/strong&gt; teams often end up with messy histories, endless merge conflicts, and uncertain deployment flows.&lt;/p&gt;

&lt;p&gt;A good branching strategy doesn’t just organize code. It shapes how your team collaborates, delivers features, fixes bugs, and ships products. In this article, we’ll explore the most popular Git branching strategies, their pros and cons, and help you decide which one fits your team.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌱 What is a Git Branch, Anyway?
&lt;/h2&gt;

&lt;p&gt;Think of Git branches as &lt;strong&gt;alternate timelines in a Marvel movie&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One timeline: you’re building a login page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another timeline: you’re fixing a nasty production bug.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another: you’re experimenting with dark mode (because why not).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Branching lets you explore all these universes without messing up the main storyline. A branch in Git is also simply a &lt;strong&gt;pointer to a commit&lt;/strong&gt;, a lightweight reference that lets you work on changes without affecting the main codebase.&lt;/p&gt;

&lt;p&gt;Why branch at all?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To isolate features until they’re ready.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To fix bugs without disturbing ongoing development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To prepare releases in a controlled way.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of branches as parallel timelines in your project. A good branching model keeps those timelines clean and manageable and it help you to avoir an interdimensional cataclysm( thanks marvel 😉 ).&lt;/p&gt;

&lt;p&gt;We have mainly 6 branch types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;main/master&lt;/strong&gt;: To prepare releases in a controlled way.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;dev/develop&lt;/strong&gt;: Integration branch for features and fixes, contains the latest development state, not necessarily production-ready.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;feature:&lt;/strong&gt; for new features or improvements, branched from &lt;code&gt;dev&lt;/code&gt;, merged back into &lt;code&gt;dev&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;release:&lt;/strong&gt; for finalizing a release, branched from &lt;code&gt;dev&lt;/code&gt;, merged into &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;dev&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;hotfix:&lt;/strong&gt; for urgent production fixes, branched from &lt;code&gt;main&lt;/code&gt;, merged into &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;dev&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;fix (optional):&lt;/strong&gt; for non-critical bug fixes, branched from &lt;code&gt;dev&lt;/code&gt; (or a release branch).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏷️ Naming git branches
&lt;/h2&gt;

&lt;p&gt;Every team is free to define its own branch naming rules, but consistency is what really matters. A common convention is to prefix branches with their type (&lt;code&gt;feature/&lt;/code&gt;, &lt;code&gt;release/&lt;/code&gt;, &lt;code&gt;hotfix/&lt;/code&gt;) and use short, descriptive names in lowercase with dashes. For example: &lt;code&gt;feature/login-page&lt;/code&gt;, &lt;code&gt;release/1.0.0&lt;/code&gt;, or &lt;code&gt;hotfix/1.0.1&lt;/code&gt;. This keeps the repository clean, makes the purpose of each branch instantly clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ The Big 6 Strategies
&lt;/h2&gt;

&lt;p&gt;Every git repository comes with a single branch, the &lt;strong&gt;main&lt;/strong&gt;/&lt;strong&gt;master&lt;/strong&gt;(its depends) which is the backbone of the project, everything rely on him. Assume that we have one git repository with his main/master. We will consider from now, a dev team working on &lt;strong&gt;n&lt;/strong&gt; mains features from feat1 to feat n.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Feature Branching&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With feature branching each feature/change/fix has its own branch created from the main branch and once the feature is completed the branch can be merged into main and be deleted.&lt;/p&gt;

&lt;p&gt;This strategy allows &lt;strong&gt;isolation of development&lt;/strong&gt;; each developer can work on their features simultaneously without affecting the main codebase. However, it can often lead to git conflicts during merges on the main branch, depending on the branch timeline, so the team should have discipline and regularly update their git branches. The diagram below explains how it works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec4jmw66l5qn7ij2kowa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fec4jmw66l5qn7ij2kowa.png" alt="feature branching" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The devs start by creating their feature branches from main (1), and the dev working on feat1 makes several commits before merging into the main branch in step 2. At this point, the feat1 branch is deleted (marked by a dotted line), and at point 3, the dev working on feat2 completes the changes by pulling from main to get its latest state. This is done to prevent conflicts during the merge at point 4, after which this branch is also deleted.&lt;/p&gt;

&lt;p&gt;The feature branching strategy is the &lt;strong&gt;building block&lt;/strong&gt; for most others branching strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Git Flow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With it, we maintain two permanent branches, a production and pre-production branch generally named &lt;strong&gt;main&lt;/strong&gt; and &lt;strong&gt;dev&lt;/strong&gt;. We can have additional branches like feature/fix/hotfix branches depending on the context, and here having good naming conventions plays a crucial role in maintaining clarity and consistency. The diagram below is a good illustration of how gitflow works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd8kmxd1elvg3ylwzyd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd8kmxd1elvg3ylwzyd2.png" alt="Git Flow" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developers break off into feature branches from dev to build cool stuff, then bring it back when it’s ready. When the project is about to ship, a release branch appears for final polish and testing before it goes live (and gets merged into both main and dev). But what if a bug sneaks into production? That’s where hotfix branches come in like firefighters, they branch straight off main, put out the fire, and then sync the fix back into both main and dev. This flow is designed for structured, release-oriented development, not immediate deployment.&lt;/p&gt;

&lt;p&gt;The result? A workflow where production stays safe, releases stay clean, and your team knows exactly where to work without stepping on each other’s toes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;GitHub Flow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If GitFlow feels a bit heavy, due to merge request everywhere, meet its lighter cousin: &lt;strong&gt;GitHub Flow&lt;/strong&gt;. This strategy was popularized by GitHub and is designed for teams that want to &lt;strong&gt;ship fast and often,&lt;/strong&gt; it’s a continuous-deployment-focused workflow . Unlike GitFlow, there’s no &lt;code&gt;develop&lt;/code&gt; branch or long-lived release branches , just &lt;code&gt;main/master&lt;/code&gt; and short-lived feature branches. With Github Flow, &lt;strong&gt;anything in the master branch is deployable&lt;/strong&gt;, if you have some feature to develop just create feature branche, make your changes, opend a pull/merge request, merge it and your changes are ready to be deployed. Little issues can be introduced, but then they can be fixed and redeployed without delay, you just have to do a &lt;strong&gt;hotfix&lt;/strong&gt; and there is no difference in the this flow between a hotfix and a very small feature, juste make your code and ship after merge on the main branch. You can lear more about &lt;a href="https://githubflow.github.io" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funpxswlegvgdq1c3rmg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funpxswlegvgdq1c3rmg0.png" alt="Github Flow" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;GitLab Flow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This flow priorise staging areas, if GiktFlow feels too heavy and GitHub Flow too light, &lt;strong&gt;GitLab Flow&lt;/strong&gt; is the middle ground.It combines the simplicity of feature branching with the flexibility of environment-based deployment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzmjix98w1q90gandr7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzmjix98w1q90gandr7f.png" alt="Gitlab Flow" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Developers still create &lt;strong&gt;feature branches&lt;/strong&gt; from &lt;code&gt;main&lt;/code&gt; (or sometimes from &lt;code&gt;develop&lt;/code&gt; if used).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Instead of multiple long-lived branches like in GitFlow, GitLab Flow emphasizes &lt;strong&gt;environments&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt; (production)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pre-production&lt;/code&gt; / &lt;code&gt;staging&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;development/dev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Each environment branch reflects a real-world deployment stage.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Features are merged into the right branch depending on where they should go..&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Code moves from &lt;code&gt;main&lt;/code&gt; → &lt;code&gt;pre-production&lt;/code&gt; → &lt;code&gt;production&lt;/code&gt;, like superheroes testing their powers in a training arena before saving the world.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5.Realease branching&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Release branching&lt;/strong&gt; is a structured approach used in the software development process. When a project is nearing a new version, a dedicated release branch is created from &lt;code&gt;main&lt;/code&gt; (or sometimes &lt;code&gt;develop&lt;/code&gt;). This branch works like a safety zone where teams can apply final adjustments, fix remaining bugs, and stabilize the codebase all without blocking or disrupting ongoing feature development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1n69lbx667w3i9katy4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1n69lbx667w3i9katy4d.png" alt="Release branching" width="525" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unlike feature branches, which focus on building specific functionalities, or hotfix branches, which exist to patch urgent production issues, release branches have a unique mission. They bring together all the work intended for the next version and provide a controlled environment to polish and prepare the product for deployment. In other words, they act as the bridge between active development and production delivery, ensuring the release is cohesive, stable, and ready to go live.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. &lt;strong&gt;Trunk-Based Development&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If GitFlow is structured and GitHub Flow is lightweight, &lt;strong&gt;Trunk-Based Development (TBD)&lt;/strong&gt; is the extreme minimalist 🪶. The principle is simple: everyone works on a single branch, the &lt;strong&gt;trunk&lt;/strong&gt; (usually &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;master&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasraq7fohrat4wkpim1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasraq7fohrat4wkpim1h.png" alt="Trunk-Based" width="676" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In trunk-based development, developers typically work on short-lived branches containing only a few small commits, unlike strategies that involve long-lived feature branches. This approach becomes particularly valuable as the codebase and team expand, helping maintain a steady flow of production releases.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧭 Choosing the Right Git Branching Strategy
&lt;/h2&gt;

&lt;p&gt;With Git as the de facto standard, teams face a critical decision: which branching strategy best supports their workflow, architecture, and release cadence? Whether you're building a monolith or orchestrating microservices, working solo or scaling across dozens of developers, the branching model you choose can accelerate or hinder your progress. This guide compares the strategies we explore above to help you pick the one that fits your workflow best.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Architecture Fit&lt;/th&gt;
&lt;th&gt;Team Size Fit&lt;/th&gt;
&lt;th&gt;Deployment Style&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feature Branching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Monolith&amp;lt;br&amp;gt;-✅ Microservices&lt;/td&gt;
&lt;td&gt;👥 Small to Large (3–50+)&lt;/td&gt;
&lt;td&gt;🌀 Moderate to fast&lt;/td&gt;
&lt;td&gt;- Isolated feature work&amp;lt;br&amp;gt;- Parallel development&amp;lt;br&amp;gt;- Code review culture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Git Flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Monolith&lt;/td&gt;
&lt;td&gt;👥 Medium to Large (10–100)&lt;/td&gt;
&lt;td&gt;🧊 Slow, staged releases&lt;/td&gt;
&lt;td&gt;- Traditional enterprise apps&amp;lt;br&amp;gt;- QA/staging environments&amp;lt;br&amp;gt;- Hotfix management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Microservices&lt;/td&gt;
&lt;td&gt;👥 Small to Medium (3–30)&lt;/td&gt;
&lt;td&gt;⚡ Continuous delivery&lt;/td&gt;
&lt;td&gt;- SaaS products&amp;lt;br&amp;gt;- Fast iteration&amp;lt;br&amp;gt;- GitHub PR workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitLab Flow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Microservices&amp;lt;br&amp;gt;-✅ Hybrid&lt;/td&gt;
&lt;td&gt;👥 Medium to Large (10–100)&lt;/td&gt;
&lt;td&gt;🌀 Flexible (CI/CD + staging)&lt;/td&gt;
&lt;td&gt;- Environment-based deployments&amp;lt;br&amp;gt;- GitLab CI/CD pipelines&amp;lt;br&amp;gt;- Complex release models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release Branching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Monolith&amp;lt;br&amp;gt;-✅ Hybrid&lt;/td&gt;
&lt;td&gt;👥 Medium to Large (10–100)&lt;/td&gt;
&lt;td&gt;🧊 Versioned releases&lt;/td&gt;
&lt;td&gt;- Long-term support&amp;lt;br&amp;gt;- Parallel feature + maintenance&amp;lt;br&amp;gt;- Regulated industries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Trunk-Based Development&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Microservices&lt;/td&gt;
&lt;td&gt;👥 Small to Medium (3–30)&lt;/td&gt;
&lt;td&gt;⚡ Continuous integration&lt;/td&gt;
&lt;td&gt;- High-velocity teams&amp;lt;br&amp;gt;- DevOps culture&amp;lt;br&amp;gt;- Feature flag usage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;At the end of the day, no single branching strategy rules them all and that’s the beauty of Git.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Feature Branching&lt;/strong&gt; gives you isolation, &lt;strong&gt;GitFlow&lt;/strong&gt; offers order, &lt;strong&gt;GitHub Flow&lt;/strong&gt; keeps things light, &lt;strong&gt;GitLab Flow&lt;/strong&gt; adds environment control, &lt;strong&gt;Release Branching&lt;/strong&gt; ensures stability, and &lt;strong&gt;Trunk-Based Development&lt;/strong&gt; powers speed.&lt;/p&gt;

&lt;p&gt;The best strategy is the one that fits &lt;strong&gt;your team’s culture, release rhythm, and tooling maturity&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
If your developers love experimenting and pushing fast, go lightweight.&lt;br&gt;&lt;br&gt;
If you’re handling production-critical systems, structure is your friend.&lt;/p&gt;

&lt;p&gt;Remember: branching strategies are tools, not rules. You can even &lt;strong&gt;mix and adapt&lt;/strong&gt; them what matters most is consistency, collaboration, and delivering awesome code.&lt;/p&gt;

&lt;p&gt;If you want to go more deeper, check these resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.gitlab.co.jp/ee/topics/gitlab_flow.html" rel="noopener noreferrer"&gt;https://docs.gitlab.co.jp/ee/topics/gitlab_flow.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://githubflow.github.io" rel="noopener noreferrer"&gt;https://githubflow.github.io&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.atlassian.com/fr/git/tutorials/comparing-workflows" rel="noopener noreferrer"&gt;https://www.atlassian.com/fr/git/tutorials/comparing-workflows&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.harness.io/blog/the-basics-of-release-branching" rel="noopener noreferrer"&gt;https://www.harness.io/blog/the-basics-of-release-branching&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://trunkbaseddevelopment.com" rel="noopener noreferrer"&gt;https://trunkbaseddevelopment.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>programming</category>
      <category>development</category>
      <category>versioning</category>
    </item>
    <item>
      <title>Getting Started with Vagrant</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Sun, 14 Sep 2025 21:35:22 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/getting-started-with-vagrant-191g</link>
      <guid>https://dev.to/trinitezinsou/getting-started-with-vagrant-191g</guid>
      <description>&lt;h3&gt;
  
  
  🧠 Introduction
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"What if you could magically spin up as many machines as you want for your test environments? No wand, just Vagrant."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Test environments can quickly become a nightmare: bad installs, version conflicts, etc. What if we could change that with a tool that makes you feel like a &lt;strong&gt;DevOps wizard&lt;/strong&gt;? 🎩✨&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Discover what Vagrant is (without falling asleep) 😴❌&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use it to create &lt;strong&gt;two Ubuntu VMs&lt;/strong&gt; 🖥️🖥️ and prepare a test environment for our series on incremental backups with Postgres + Barman&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And test our setup like pros 🧪&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🪄 What is Vagrant?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Vagrant is kind of like Docker, but for VMs. It's your conductor for VirtualBox, VMware, Hyper-V, and other hypervisors. It's a super reliable tool to manage complete environments with real virtual machines in a simple and automated way."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's a tool developed by &lt;a href="https://www.hashicorp.com" rel="noopener noreferrer"&gt;Hashicorp&lt;/a&gt; that makes it easy to manage VMs with fully isolated dependencies and configurations, all in a unique and disposable environment.&lt;/p&gt;

&lt;p&gt;You write a &lt;code&gt;Vagrantfile&lt;/code&gt;, type &lt;code&gt;vagrant up&lt;/code&gt;, and boom 💥: your machine(s) is(are) ready to use. No need to click through 27 buttons in VirtualBox or fight with Hyper-V.&lt;/p&gt;

&lt;p&gt;Vagrant saves you from:&lt;/p&gt;

&lt;p&gt;❌ Downloading an ISO&lt;br&gt;&lt;br&gt;
❌ Clicking through the installer manually&lt;br&gt;&lt;br&gt;
❌ Struggling with networking and scripts&lt;br&gt;&lt;br&gt;
✅ You can &lt;strong&gt;do everything automatically&lt;/strong&gt;, and &lt;strong&gt;reset your environment anytime&lt;/strong&gt;, like a quick save in your dev life.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔍 Why is it useful?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🔄 &lt;strong&gt;Easy testing&lt;/strong&gt;: want to test a Postgres config? SSH? A cluster? A network lab? Boom, spin up a VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;💥 &lt;strong&gt;Safe&lt;/strong&gt;: easily prepare demos or tutorials without polluting your main machine. If you break everything, just run &lt;code&gt;vagrant destroy &amp;amp;&amp;amp; vagrant up&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🤝 &lt;strong&gt;Shareable&lt;/strong&gt;: working in a team? Commit your &lt;code&gt;Vagrantfile&lt;/code&gt; and everyone gets &lt;em&gt;the same environment&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🧪 &lt;strong&gt;Closer to production&lt;/strong&gt;: you can create environments that &lt;em&gt;really mimic&lt;/em&gt; a real server (unlike Docker). Perfect for learning sysadmin or DevOps.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🛠️ How does it work?
&lt;/h3&gt;

&lt;p&gt;Vagrant relies on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A provider&lt;/strong&gt; (usually VirtualBox or Hyper-V) to run the machines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Boxes&lt;/strong&gt;: pre-built system images deployable in any Vagrant environment. They're essentially packaged distributions for uniform deployment. You can explore official boxes &lt;a href="https://portal.cloud.hashicorp.com/vagrant/discover" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A Vagrantfile&lt;/strong&gt; (your recipe): the file where the magic is defined&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scripts or tools to &lt;strong&gt;provision&lt;/strong&gt; the machine (install software, configure base services)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vagrant will provision the machine based on what's described in the Vagrantfile (usually in the project root). A Vagrantfile is a Ruby file, but it doesn’t require deep Ruby knowledge. It defines the machine specs (storage, RAM, network, etc.) and sets up the required tools for it to run properly.&lt;/p&gt;
&lt;h2&gt;
  
  
  🎓 Getting Started with Vagrant
&lt;/h2&gt;

&lt;p&gt;Next, we’ll get hands-on with Vagrant and set up a lab for our incremental backup series with Postgres.&lt;br&gt;&lt;br&gt;
In the end, we’ll boot two VMs: one with Postgres, and another with Barman.&lt;/p&gt;
&lt;h3&gt;
  
  
  🚀 &lt;strong&gt;Installing Vagrant&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can install Vagrant via the CLI or by using an executable from the &lt;a href="https://developer.hashicorp.com/vagrant/downloads#linux" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
You’ll also need a working VirtualBox setup, which is the provider we’ll use.&lt;/p&gt;
&lt;h3&gt;
  
  
  🛠️ Using Vagrant
&lt;/h3&gt;

&lt;p&gt;Let's create our first &lt;code&gt;Vagrantfile&lt;/code&gt; with the minimal config to run a VM. Create a folder and inside it, a &lt;code&gt;Vagrantfile&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu/focal64"&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vagrantbox"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vagrant provides a wide variety of commands to manage the different components of the Vagrant ecosystem. For example, &lt;code&gt;vagrant box list&lt;/code&gt; and &lt;code&gt;vagrant box add box_name&lt;/code&gt; respectively list the boxes available locally and add a box to the local collection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant box add ubuntu/focal64
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; box: Loading metadata &lt;span class="k"&gt;for &lt;/span&gt;box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt;
    box: URL: https://vagrantcloud.com/api/v2/vagrant/ubuntu/focal64
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1&lt;span class="o"&gt;)&lt;/span&gt; hyperv
2&lt;span class="o"&gt;)&lt;/span&gt; libvirt
3&lt;span class="o"&gt;)&lt;/span&gt; virtualbox
4&lt;span class="o"&gt;)&lt;/span&gt; vmware_desktop

Enter your choice: 3
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; box: Adding box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;v2004.01&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;provider: virtualbox
    box: Downloading: https://vagrantcloud.com/ubuntu/boxes/focal64/versions/20240821.0.1/providers/virtualbox/unknown/vagrant.box
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant box list             
ubuntu/bionic64 &lt;span class="o"&gt;(&lt;/span&gt;virtualbox, 20230607.0.0&lt;span class="o"&gt;)&lt;/span&gt;
ubuntu/focal64  &lt;span class="o"&gt;(&lt;/span&gt;virtualbox, 20240220.0.0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More info on box management &lt;a href="https://developer.hashicorp.com/vagrant/docs/cli/box" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Next, let's verify that the syntax of the file is correct using &lt;code&gt;vagrant validate&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
If there are no errors, you will see the following message: Vagrantfile validated successfully.&lt;/p&gt;

&lt;p&gt;Then launch your VM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant up             
Bringing machine &lt;span class="s1"&gt;'default'&lt;/span&gt; up with &lt;span class="s1"&gt;'virtualbox'&lt;/span&gt; provider...
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Importing base box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt;...
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Matching MAC address &lt;span class="k"&gt;for &lt;/span&gt;NAT networking...
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Checking &lt;span class="k"&gt;if &lt;/span&gt;box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt; version &lt;span class="s1"&gt;'20240220.0.0'&lt;/span&gt; is up to date...
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: A newer version of the box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;provider &lt;span class="s1"&gt;'virtualbox'&lt;/span&gt; is
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: available! You currently have version &lt;span class="s1"&gt;'20240220.0.0'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; The latest is version
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: &lt;span class="s1"&gt;'20240821.0.1'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; Run &lt;span class="sb"&gt;`&lt;/span&gt;vagrant box update&lt;span class="sb"&gt;`&lt;/span&gt; to update.
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Setting the name of the VM: ocr_default_1749933808776_2967
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Clearing any previously &lt;span class="nb"&gt;set &lt;/span&gt;network interfaces...
&lt;span class="o"&gt;[&lt;/span&gt;...]

&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant status
Current machine states:

default                   running &lt;span class="o"&gt;(&lt;/span&gt;virtualbox&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;...]Check the status:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the VM is up and running, we can connect to it via SSH to perform various operations using the command &lt;code&gt;vagrant ssh machine_name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vagrant can also be effectively used in a context that requires a multi-tier architecture — i.e., multiple machines (sometimes with different operating systems) at once, as is often the case in production. You simply need to define as many VM configurations as needed.&lt;/p&gt;

&lt;p&gt;Let’s now connect to the machine we’ve prepared so far.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant ssh default             
Welcome to Ubuntu 20.04.6 LTS &lt;span class="o"&gt;(&lt;/span&gt;GNU/Linux 5.4.0-172-generic x86_64&lt;span class="o"&gt;)&lt;/span&gt;

 &lt;span class="k"&gt;*&lt;/span&gt; Documentation:  https://help.ubuntu.com
 &lt;span class="k"&gt;*&lt;/span&gt; Management:     https://landscape.canonical.com
 &lt;span class="k"&gt;*&lt;/span&gt; Support:        https://ubuntu.com/pro
&lt;span class="o"&gt;[&lt;/span&gt;...]
vagrant@vagrantbox:~&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The diagram below illustrates the &lt;strong&gt;typical lifecycle of a Vagrant virtual machine&lt;/strong&gt;, from initialization to complete removal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4agxxf1cm6b5lklm5huj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4agxxf1cm6b5lklm5huj.png" alt="Vagrant Lifecycle" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;vagrant init&lt;/code&gt; creates a Vagrantfile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Configure the Vagrantfile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is an important step in setting up the &lt;code&gt;Vagrantfile&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Here, we define everything needed to prepare the machine (provisioning and more). Then, using the &lt;code&gt;vagrant up&lt;/code&gt; command, we start the virtual machine. If it doesn’t exist yet, it will be created and provisioned.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Running&lt;/code&gt;&lt;br&gt;&lt;br&gt;
The machine is now running. From this point on, you have several options available to you:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* `vagrant reload` : restart the VM with the updated config

* `vagrant suspend` / `vagrant resume` : to suspend and resume the VM

* `vagrant halt` : to shut down the VM properly

* `vagrant provision` : rerun the provisioning scripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Destroy&lt;/code&gt;
With &lt;code&gt;vagrant destroy&lt;/code&gt;, the VM is completely removed.
You then return to a clean state.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🚀 Provisioning Vagrant VMs
&lt;/h2&gt;

&lt;p&gt;Now that our base environment is defined in the Vagrantfile, it's time to prepare each machine so they are ready to use that is, install everything necessary to operate them. This is the provisioning step.&lt;/p&gt;

&lt;p&gt;Vagrant provides several interfaces to provision our VMs: shell, file, Chef, Docker, Ansible, etc.&lt;br&gt;&lt;br&gt;
Next, we will explore some of these provisioners and prepare what’s needed to provision our VMs for the Postgres and Vagrant lab.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Shell Provisioner
&lt;/h3&gt;

&lt;p&gt;It allows you to specify a series of instructions to execute in order to provision the machine. This interface supports two options by default: &lt;code&gt;inline&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
These let you specify either a command directly within the Vagrantfile or the path to a ready-to-use bash script to set up the machine, as shown in the example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# ... others configuration&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="s2"&gt;"echo Hello, World"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# ... others configuration&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="sr"&gt;/path/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bash&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. File Provisioner
&lt;/h3&gt;

&lt;p&gt;It allows you to &lt;strong&gt;mount a file or folder&lt;/strong&gt; from the host machine to the virtual machine.&lt;br&gt;&lt;br&gt;
This mechanism is especially useful for &lt;strong&gt;sharing provisioning scripts, configuration files, or datasets&lt;/strong&gt; between the host and the VM without having to manually copy them each time.&lt;/p&gt;

&lt;p&gt;For example, to copy a file to the host machine, the syntax is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# ... others configuration&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;source: &lt;/span&gt;&lt;span class="s2"&gt;"~/path/to/host/folder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;destination: &lt;/span&gt;&lt;span class="s2"&gt;"$HOME/remote/newfolder"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This copy is one-time and does not synchronize the file state.&lt;br&gt;&lt;br&gt;
To synchronize the file state between the host and the VM, the configuration should be as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# ... others configuration&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synced_folder&lt;/span&gt; &lt;span class="s2"&gt;"src/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"/srv/website"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information about synchronization, please consult the official documentation &lt;a href="https://developer.hashicorp.com/vagrant/docs/synced-folders/basic_usage" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Ansible Provisioner
&lt;/h3&gt;

&lt;p&gt;Unlike traditional shell scripts, the Ansible provisioner allows you to &lt;strong&gt;describe the desired state of a system in a declarative way&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
This means you write "playbooks" (YAML files) that define what you want to achieve (e.g., PostgreSQL installed, a user created, a service started), and Ansible takes care of making the necessary changes to reach that state, &lt;strong&gt;without unnecessarily repeating tasks that have already been done&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use Ansible with vagrant?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;✅ More readable, structured, and reusable code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🔁 Idempotence: running a playbook again doesn’t change anything if everything is already in place.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;⚙️ Easy to maintain, especially for complex or multi-machine environments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vagrant can run Ansible as &lt;strong&gt;either a local or remote provisioner&lt;/strong&gt;, depending on whether Ansible is installed on the host or on the VM itself.&lt;/p&gt;

&lt;p&gt;Here is a minimal example in a Vagrantfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"ansible"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;playbook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"playbook.yml"&lt;/span&gt;
  &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inventory_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"inventory.ini"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Practical: Building the PostgreSQL + Barman Lab
&lt;/h2&gt;

&lt;p&gt;It’s time to get hands-on and build our test environment.&lt;br&gt;&lt;br&gt;
The goal of this phase is to &lt;strong&gt;create two virtual machines&lt;/strong&gt; using Vagrant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🐘 A first VM with &lt;strong&gt;PostgreSQL&lt;/strong&gt; installed; it will simulate our source database,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📦 A second VM with &lt;strong&gt;Barman&lt;/strong&gt; installed; it will represent an administrator workstation or a control machine from which we can manage our backups.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will automate the installation of each component using &lt;strong&gt;Bash provisioning scripts&lt;/strong&gt;.The &lt;code&gt;Vagrantfile&lt;/code&gt; will define the architecture of our lab and execute the scripts automatically when the machines start.&lt;/p&gt;

&lt;p&gt;Let's start by creating the Vagrantfile and the scripts needed to install Postgres and Barman.&lt;/p&gt;

&lt;p&gt;Vagrantfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Vagrantfile&lt;/span&gt;
&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"vm1_postgres"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu/jammy64"&lt;/span&gt;
    &lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"postgres"&lt;/span&gt;
    &lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.10"&lt;/span&gt;
    &lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s2"&gt;"scripts/setup_postgres.sh"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"vm2_vagrant"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu/jammy64"&lt;/span&gt;
    &lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vagrant"&lt;/span&gt;
    &lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.11"&lt;/span&gt;
    &lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s2"&gt;"scripts/setup_vagrant.sh"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;scripts/setup_postgres.sh&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[INFO] Installing PostgreSQL..."&lt;/span&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; postgresql postgresql-contrib

psql &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[OK] PostgreSQL installed"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;scripts/setup_barman.sh&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[INFO] Installing Barman..."&lt;/span&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; barman

barman &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[OK] Barman installed"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧩 Conclusion
&lt;/h2&gt;

&lt;p&gt;We have just discovered Vagrant and, in practice, laid the foundation for a test environment by setting up two virtual machines: one with &lt;strong&gt;PostgreSQL&lt;/strong&gt; installed, and the other with &lt;strong&gt;Barman&lt;/strong&gt;, our backup tool in the incremental backups series.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;strong&gt;Vagrant&lt;/strong&gt; and provisioning scripts, we have automated the deployment of this environment, allowing us to easily reproduce our tests, save time, and avoid manual errors.&lt;/p&gt;

&lt;p&gt;What we set up here is not limited to the context of Postgres and Barman: this type of lab can serve as a &lt;strong&gt;generic base for all kinds of DevOps practices&lt;/strong&gt;, system experiments, or technical tests in isolated environments.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧰 A simple, reproducible, and extensible foundation — ideal for learning, testing, breaking… and starting over!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;See you soon in the next post on this blog.&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>ubuntu</category>
      <category>devops</category>
      <category>vagrant</category>
    </item>
    <item>
      <title>A la découverte de vagrant</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Sun, 14 Sep 2025 21:33:55 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/a-la-decouverte-de-vagrant-4pbf</link>
      <guid>https://dev.to/trinitezinsou/a-la-decouverte-de-vagrant-4pbf</guid>
      <description>&lt;h3&gt;
  
  
  🧠 Introduction
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Et si tu pouvais faire apparaître autant de machines comme par magie, autant que tu en voudrais pour tes environnementes tests? Pas de baguette, juste Vagrant."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Les environnements de test peuvent vite virer au cauchemar : installation foireuse, conflits de versions, etc. Et si on changeait ça avec un outil qui te fait sentir comme un &lt;strong&gt;DevOps sorcier&lt;/strong&gt; ? 🎩✨&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dans cet article, on va :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Découvrir ce qu’est Vagrant (sans s’endormir) 😴❌&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;L’utiliser pour créer &lt;strong&gt;deux VMs Ubuntu&lt;/strong&gt; 🖥️🖥️ et préparer un environnement de test pour notre série sur les sauvegardes incrémentales avec Postgre+Barman&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Et tester notre setup comme des pros 🧪&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🪄 Vagrant, c’est quoi ce truc ?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Vagrant, c’est un peu comme Docker, mais pour les VM. C’est ton chef d’orchestre pour VirtualBox, VMware, Hyper-V, et autres joyeusetés. C’est un outil ultra fiable pour gérer des environnements complets avec de vraies machines virtuelles de manière simple et automatisée."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il s’agit d’un outil développé par &lt;a href="https://www.hashicorp.com/fr" rel="noopener noreferrer"&gt;Hashicorp&lt;/a&gt; permettant de gérer facilement des VMs avec une isolation totale des dépendances et des configurations, tout ceci dans un environement unique et jetable.&lt;/p&gt;

&lt;p&gt;Tu lui écris un &lt;code&gt;Vagrantfile&lt;/code&gt;, tu tapes &lt;code&gt;vagrant up&lt;/code&gt;, et boum 💥 : ta(tes) machine(s) est(sont) là, toute prête à etre utilisée(s). Pas besoin de cliquer sur 27 boutons dans VirtualBox ou te battre avec Hyper-V.&lt;/p&gt;

&lt;p&gt;Vagrant t’évite de :&lt;/p&gt;

&lt;p&gt;❌ Aller télécharger une ISO&lt;br&gt;&lt;br&gt;
❌ Suivre l’installateur à la main&lt;br&gt;&lt;br&gt;
❌ Galérer avec le réseau et les scripts&lt;br&gt;&lt;br&gt;
✅ Il te permet de &lt;strong&gt;tout faire automatiquement&lt;/strong&gt;, et de &lt;strong&gt;réinitialiser ton environnement quand tu veux&lt;/strong&gt;, comme une sauvegarde rapide de ta vie de dev.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔍 Pourquoi c’est pratique ?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🔄 &lt;strong&gt;Test facile&lt;/strong&gt; : tu veux tester une config Postgres ? SSH ? Un cluster ? Un lab réseau? Boom, tu spin une VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;💥 &lt;strong&gt;Sans risque&lt;/strong&gt; : tu peux facilement préparer des démos ou tutoriels sans polluer ta machine principale. Si tu casses tout, tu fais &lt;code&gt;vagrant destroy &amp;amp;&amp;amp; vagrant up&lt;/code&gt; et ça repart.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🤝 &lt;strong&gt;Partageable&lt;/strong&gt; : tu bosses en équipe ? Tu commits ton &lt;code&gt;Vagrantfile&lt;/code&gt; et tout le monde a &lt;em&gt;le même environnement&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🧪 &lt;strong&gt;Proche de la prod&lt;/strong&gt; : tu peux créer des environnements qui &lt;em&gt;imitent vraiment&lt;/em&gt; un serveur réel (contrairement à Docker qui fait du container). Tu as désormais donc tout pour apprendre l’admin système ou le DevOps.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🛠️ Comment ça fonctionne ?
&lt;/h3&gt;

&lt;p&gt;Vagrant repose sur :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Un provider&lt;/strong&gt; (généralement VirtualBox ou Hyper-V) pour faire tourner les machines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Les boxes :&lt;/strong&gt; ce sont des images de systèmes déployables au sein de tout environnement Vagrant. Il s'agit en pratique d'une façon de packager une distribution afin de permettre un déploiement uniforme quel que soit le système d'exploitation ou l'hyperviseur utilisé. Tu peux consulter le depot officiel des boxes de vagrant &lt;a href="https://portal.cloud.hashicorp.com/vagrant/discover" rel="noopener noreferrer"&gt;ici&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Un Vagrantfile&lt;/strong&gt; (ta recette): le fichier dans lequel toute la magie se définie.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Des scripts ou outils pour &lt;strong&gt;provisionner&lt;/strong&gt; la machine (installer des logiciels, configurer les services de base)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vagrant va provisioner la machine en fonction de ce qui est décrit dans le fichier Vagrantfile (souvent à la racine du projet). Un fichier Vagrantfile est un fichier Ruby, dont le contenu ne nécessite pas une grande connaisance de Ruby. Il sert à décrire toutes les caractéristiques de la machine cible (stockages, Ram, réseaux, etc) et aussi à préparer tous les utilitaires de base nécessaire au bon fonctionnement de la machine.&lt;/p&gt;
&lt;h2&gt;
  
  
  🎓 Premiers pas avec vagrant
&lt;/h2&gt;

&lt;p&gt;Dans la suite nous allons prendre en main vagrant et mettre en place un lab pour la série à propos des sauvegardes incrémentales avec postgres. On mettra dans la suite notre lab en place sur une machine Ubuntu.&lt;br&gt;&lt;br&gt;
Il s’agira à la fin de pouvoir démarrer deux VM sur lequelles nous allons installer respectivement barman et postgres.&lt;/p&gt;
&lt;h3&gt;
  
  
  🚀 &lt;strong&gt;Installation de Vagrant&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tu peux installer vagrant soit en ligne de commande soit avec un executable disponible sur la documentation officielle &lt;a href="https://developer.hashicorp.com/vagrant/downloads#linux" rel="noopener noreferrer"&gt;ici&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Il faudra aussi VirtualBox fonctionnel pour la suite, c’est le provider vagrant que nous allons utiliser dans la suite&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;🛠️&lt;/strong&gt; Manipulation de Vagrant
&lt;/h3&gt;

&lt;p&gt;Pour démarrer nous allons simplement écrire notre premier Vagrantfile, on y mettra le minimum d’information pour faire tourner une VM. Il faudra créer un dossier qui contiendra un fichier Vagrantfile dont le contenu pourra être le suivant&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu/focal64"&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vagrantbox"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vagrant mets à disposition une large variété de commande pour manipuler les différentes composantes de l’ecosystème vagrant comme &lt;code&gt;vagrant box list&lt;/code&gt; ou &lt;code&gt;vagrand box add box_name&lt;/code&gt; pour respectivement lister les box disponibles localement, et ajouter une box à la collection locale.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant box add ubuntu/focal64
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; box: Loading metadata &lt;span class="k"&gt;for &lt;/span&gt;box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt;
    box: URL: https://vagrantcloud.com/api/v2/vagrant/ubuntu/focal64
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1&lt;span class="o"&gt;)&lt;/span&gt; hyperv
2&lt;span class="o"&gt;)&lt;/span&gt; libvirt
3&lt;span class="o"&gt;)&lt;/span&gt; virtualbox
4&lt;span class="o"&gt;)&lt;/span&gt; vmware_desktop

Enter your choice: 3
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; box: Adding box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;v2004.01&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;provider: virtualbox
    box: Downloading: https://vagrantcloud.com/ubuntu/boxes/focal64/versions/20240821.0.1/providers/virtualbox/unknown/vagrant.box
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant box list             
ubuntu/bionic64 &lt;span class="o"&gt;(&lt;/span&gt;virtualbox, 20230607.0.0&lt;span class="o"&gt;)&lt;/span&gt;
ubuntu/focal64  &lt;span class="o"&gt;(&lt;/span&gt;virtualbox, 20240220.0.0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus d’information sur la gestion des box vagrant &lt;a href="https://developer.hashicorp.com/vagrant/docs/cli/box" rel="noopener noreferrer"&gt;ici&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Vérifions ensuite que la syntaxe du fichier est correcte avec &lt;code&gt;vagrant validate&lt;/code&gt;. S’il n’y a aucune erreur tu verras le message suivant &lt;em&gt;Vagrantfile validated successfully.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A ce stade s’il n’y a aucune erreur, on peut lancer notre vm avec la commande &lt;code&gt;vagrant up&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant up             
Bringing machine &lt;span class="s1"&gt;'default'&lt;/span&gt; up with &lt;span class="s1"&gt;'virtualbox'&lt;/span&gt; provider...
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Importing base box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt;...
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Matching MAC address &lt;span class="k"&gt;for &lt;/span&gt;NAT networking...
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Checking &lt;span class="k"&gt;if &lt;/span&gt;box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt; version &lt;span class="s1"&gt;'20240220.0.0'&lt;/span&gt; is up to date...
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: A newer version of the box &lt;span class="s1"&gt;'ubuntu/focal64'&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;provider &lt;span class="s1"&gt;'virtualbox'&lt;/span&gt; is
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: available! You currently have version &lt;span class="s1"&gt;'20240220.0.0'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; The latest is version
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: &lt;span class="s1"&gt;'20240821.0.1'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; Run &lt;span class="sb"&gt;`&lt;/span&gt;vagrant box update&lt;span class="sb"&gt;`&lt;/span&gt; to update.
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Setting the name of the VM: ocr_default_1749933808776_2967
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; default: Clearing any previously &lt;span class="nb"&gt;set &lt;/span&gt;network interfaces...
&lt;span class="o"&gt;[&lt;/span&gt;...]

&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant status
Current machine states:

default                   running &lt;span class="o"&gt;(&lt;/span&gt;virtualbox&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Une fois la VM lancée, on pourra s’y connecter par ssh pour effectuer nos différentes manipulations avec la commande &lt;code&gt;vagrant ssh nom_machine&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Vagrant peut etre bien aussi utilisé dans un context pour répondre à un schéma d’architecture multi-tiers ie plusieurs machines(parfois avec différents OS) à la fois comme c’est souvent le cas en production; il suffi juste d’alligner autant de description de VM qu’il nous faut.&lt;/p&gt;

&lt;p&gt;Connectons nous à présent à notre machine jusqu’ici préparée&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant ssh default             
Welcome to Ubuntu 20.04.6 LTS &lt;span class="o"&gt;(&lt;/span&gt;GNU/Linux 5.4.0-172-generic x86_64&lt;span class="o"&gt;)&lt;/span&gt;

 &lt;span class="k"&gt;*&lt;/span&gt; Documentation:  https://help.ubuntu.com
 &lt;span class="k"&gt;*&lt;/span&gt; Management:     https://landscape.canonical.com
 &lt;span class="k"&gt;*&lt;/span&gt; Support:        https://ubuntu.com/pro
&lt;span class="o"&gt;[&lt;/span&gt;...]
vagrant@vagrantbox:~&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le diagramme ci-dessous illustre &lt;strong&gt;le parcours typique d'une machine virtuelle Vagrant&lt;/strong&gt;, depuis son initialisation jusqu'à sa suppression complète.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6o1y178iu6ce2cudoy5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6o1y178iu6ce2cudoy5o.png" alt="Cycle de vie VM Vagrant" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Étapes principales
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;vagrant init&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Initialise un projet Vagrant en créant un &lt;code&gt;Vagrantfile&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Configured vagrantfile&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Etape importante pour la mise en place du Vagrantfile. On y mettre le necessaire pour la préparation de la machine(provisonnement et autre). Ensuite grace à la commande &lt;code&gt;vagrant up&lt;/code&gt; on démarre la machine virtuelle. Si elle n’existe pas, elle est créée et provisionnée.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Running&lt;/code&gt;&lt;br&gt;&lt;br&gt;
La machine est en cours d'exécution. À partir de là, plusieurs options s’offrent à toi :&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* `vagrant reload` : redémarre la VM avec la config à jour

* `vagrant suspend` / `vagrant resume` : suspend et reprend l’exécution

* `vagrant halt` : éteint la VM proprement

* `vagrant provision` : réexécute les scripts de provisioning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Destroy&lt;/code&gt;
Avec &lt;code&gt;vagrant destroy&lt;/code&gt;, la VM est complètement supprimée. Tu reviens alors à un état propre.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🚀 Provisionner les VM vagrant
&lt;/h2&gt;

&lt;p&gt;Maintenant que notre environnement de base est défini dans le &lt;code&gt;Vagrantfile&lt;/code&gt;, il est temps de &lt;strong&gt;préparer chaque machine&lt;/strong&gt; pour qu’elles soient prêtes à l’emploi ie installer le nécessaire qu’il faut pour les utiliser; c’est l’etape du provisionnement.&lt;/p&gt;

&lt;p&gt;Vagrant met à disposition plusieurs interfaces pour provisionner nos VM: les provisionneur de type shell, fichier, chef, docker, ansible, etc. Dans la suite, nous allons découvrir quelques un de ces provisonneurs et préparer le nécessaire pour provisonner nos VM pour le lab sur postgres et vagrant.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Provisionner Shell&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Il permet de spécifier une suite d’instruction à exécuter pour provisionner la machine. Cette interface supporte par defaut deux options &lt;code&gt;inline&lt;/code&gt; et &lt;code&gt;path&lt;/code&gt; pour respectivement spécifier une commande à directement saisir dans le vagranfile ou le chemin vers un script bash deja pret à l’emploi pour préparer notre machine comme le montre l’exemple ci dessous&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vagrant.configure("2") do |config|
  # ... autre configuration
  config.vm.provision "shell",
    inline: "echo Hello, World"
end

Vagrant.configure("2") do |config|
  # ... autre configuration
  config.vm.provision "shell", path: /path/to/my/bash/script
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Provisionner fichier&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Il permet de &lt;strong&gt;monter un fichier ou un dossier&lt;/strong&gt; depuis la machine hôte vers la machine virtuelle.&lt;br&gt;&lt;br&gt;
Ce mécanisme est particulièrement utile lorsqu’il s’agit de &lt;strong&gt;partager des scripts de provisionnement, des fichiers de configuration ou des jeux de données&lt;/strong&gt; entre l’hôte et la VM, sans avoir à les copier manuellement à chaque fois. Pour copier par exemple un fichier vers la machine hote, la syntaxe est la suivante:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vagrant.configure("2") do |config|
  # ... autre configuration

  config.vm.provision "file", source: "~/path/to/host/folder", destination: "$HOME/remote/newfolder"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette copie est ponctuelle et ne synchronise pas l’etat des fichiers. Pour synchroniser l’etat des fichiers entre l’hote et la VM, la configuration doit se présenter comme suit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vagrant.configure("2") do |config|
  # ... autre configuration

  config.vm.synced_folder "src/", "/srv/website"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour plus d’informations sur la sychronisation consulter la documentation officielle &lt;a href="https://developer.hashicorp.com/vagrant/docs/synced-folders/basic_usage" rel="noopener noreferrer"&gt;ici&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Provisionner ansible&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Contrairement aux scripts shell classiques, le provisionneur Ansible permet de &lt;strong&gt;décrire l’état attendu d’un système de manière déclarative&lt;/strong&gt;. Cela signifie que tu écris des "playbooks" (fichiers YAML) qui définissent ce que tu veux obtenir (ex. : PostgreSQL installé, un utilisateur créé, un service démarré), et Ansible s’occupe de faire le nécessaire pour atteindre cet état, &lt;strong&gt;sans répéter inutilement les tâches déjà effectuées&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;🔍 &lt;strong&gt;Avantages d’utiliser Ansible avec Vagrant&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;✅ Code plus lisible, structuré et réutilisable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🔁 Idempotence : rejouer un playbook ne modifie rien si tout est déjà en place.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;⚙️ Facile à maintenir, surtout pour des environnements complexes ou multi-machines.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vagrant peut exécuter Ansible &lt;strong&gt;en tant que provisionneur local ou distant&lt;/strong&gt;, selon que Ansible est installé sur l’hôte ou sur la VM elle-même.&lt;/p&gt;

&lt;p&gt;Voici un exemple minimal dans un &lt;code&gt;Vagrantfile&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"ansible"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;playbook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"playbook.yml"&lt;/span&gt;
  &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inventory_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"inventory.ini"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Phase pratique : mise en place du lab PostgreSQL + Barman
&lt;/h2&gt;

&lt;p&gt;Il est temps de passer à la pratique et de construire notre environnement de test.&lt;br&gt;&lt;br&gt;
L’objectif de cette phase est de &lt;strong&gt;créer deux machines virtuelles&lt;/strong&gt; à l’aide de Vagrant :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🐘 Une première VM avec &lt;strong&gt;PostgreSQL&lt;/strong&gt; installé; elle simulera notre base de données source,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📦 Une seconde VM avec &lt;strong&gt;barman&lt;/strong&gt; installé; elle représentera un poste administrateur ou une machine de contrôle depuis laquelle on pourra gérer nos sauvegardes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nous allons automatiser l’installation de chaque composant à l’aide de &lt;strong&gt;scripts de provisionnement Bash&lt;/strong&gt;. Le &lt;code&gt;Vagrantfile&lt;/code&gt; définira l’architecture de notre lab et exécutera les scripts automatiquement au démarrage des machines.&lt;/p&gt;

&lt;p&gt;Commençons par créer le fichier &lt;code&gt;Vagrantfile&lt;/code&gt; et les scripts nécessaires à l’installation de postgres et barman.&lt;/p&gt;

&lt;p&gt;Vagranfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Vagrantfile&lt;/span&gt;
&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"vm1_postgres"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu/jammy64"&lt;/span&gt;
    &lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"postgres"&lt;/span&gt;
    &lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.10"&lt;/span&gt;
    &lt;span class="n"&gt;vm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s2"&gt;"scripts/setup_postgres.sh"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"vm2_vagrant"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ubuntu/jammy64"&lt;/span&gt;
    &lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vagrant"&lt;/span&gt;
    &lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.11"&lt;/span&gt;
    &lt;span class="n"&gt;vm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s2"&gt;"scripts/setup_vagrant.sh"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;scripts/setup_postgres.sh&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[INFO] Installation de PostgreSQL..."&lt;/span&gt;

&lt;span class="c"&gt;# Mise à jour des paquets&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update

&lt;span class="c"&gt;# Installation de PostgreSQL&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; postgresql postgresql-contrib

&lt;span class="c"&gt;# Vérification&lt;/span&gt;
psql &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[OK] PostgreSQL installé"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;scripts/setup_barman.sh&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[INFO] Installation de Barman..."&lt;/span&gt;

&lt;span class="c"&gt;# Mise à jour des paquets&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update

&lt;span class="c"&gt;# Installation de Barman (et dépendances)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; barman

&lt;span class="c"&gt;# Vérification&lt;/span&gt;
barman &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[OK] Barman installé"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧩 Conclusion
&lt;/h2&gt;

&lt;p&gt;Nous venons de découvrir Vagrant et en application poser les bases d’un environnement de test en mettant en place deux machines virtuelles : l'une avec &lt;strong&gt;PostgreSQL&lt;/strong&gt; installé, et l'autre avec &lt;strong&gt;Barman&lt;/strong&gt;, notre outil de sauvegarde dans la &lt;a href="https://trinitezinsou.hashnode.dev/series/sauvegardes-incrementales-avec-postgresql" rel="noopener noreferrer"&gt;série sur les sauvegardes incrémentales&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Grâce à &lt;strong&gt;Vagrant&lt;/strong&gt; et aux scripts de provisionnement, nous avons automatisé le déploiement de cet environnement, ce qui nous permettra de reproduire facilement nos tests, de gagner du temps, et d’éviter les erreurs manuelles.&lt;/p&gt;

&lt;p&gt;Ce que nous avons mis en place ici ne se limite pas au contexte de postgres et de barman : ce type de lab peut servir de &lt;strong&gt;base générique pour toutes sortes de pratiques DevOps&lt;/strong&gt;, d’expérimentations systèmes ou de tests techniques en environnement isolé.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧰 Un socle simple, reproductible et extensible idéal pour apprendre, tester, casser… et recommencer !&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;À très bientôt pour le prochain article de ce blog&lt;/p&gt;

</description>
      <category>vagrant</category>
      <category>linux</category>
      <category>devops</category>
      <category>virtualmachine</category>
    </item>
    <item>
      <title>Setting up incremental backups with PostgreSql - Recovery - Part 3</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Sat, 13 Sep 2025 11:21:08 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/setting-up-incremental-backups-with-postgresql-recovery-part-3-4foi</link>
      <guid>https://dev.to/trinitezinsou/setting-up-incremental-backups-with-postgresql-recovery-part-3-4foi</guid>
      <description>&lt;h2&gt;
  
  
  🧭 Introduction
&lt;/h2&gt;

&lt;p&gt;Setting up backups is essential. But knowing how to &lt;strong&gt;restore them effectively when needed&lt;/strong&gt; is even more crucial. This is where &lt;strong&gt;PITR&lt;/strong&gt; (Point-In-Time Recovery) comes into play, a powerful feature offered by PostgreSQL and fully managed by Barman.&lt;/p&gt;

&lt;p&gt;Whether it’s to correct a human error, revert after a failed deployment, or analyze the state of the database at a specific moment, Barman allows you to &lt;strong&gt;bring PostgreSQL back in time&lt;/strong&gt;, replaying only the changes up to a defined point.&lt;/p&gt;

&lt;p&gt;In this chapter, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What PITR actually is,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The prerequisites for it to work,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And most importantly, &lt;strong&gt;how to use it step by step&lt;/strong&gt; with Barman, reliably.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ready to travel back in time with PostgreSQL? Let’s go 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  🕰️ What is PITR (Point-In-Time Recovery)?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Point-In-Time Recovery&lt;/strong&gt;, or &lt;strong&gt;PITR&lt;/strong&gt;, is a powerful PostgreSQL feature that allows you to restore a database to &lt;strong&gt;a precise moment in the past&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
It’s a bit like a time machine 🕳️🕒.&lt;/p&gt;

&lt;p&gt;Imagine a bug or human error corrupted data this morning at 10:30 AM. With PITR, you can restore the database &lt;strong&gt;exactly as it was at 09:29 AM&lt;/strong&gt;, just before the issue.&lt;/p&gt;

&lt;p&gt;For this to work, PostgreSQL logs all database writes in files called &lt;strong&gt;WALs (Write Ahead Logs)&lt;/strong&gt;. These files contain the history of all changes made to the database.&lt;br&gt;&lt;br&gt;
Barman uses these files to &lt;strong&gt;replay the database history&lt;/strong&gt; up to the chosen moment, starting from a full backup. It essentially rewinds the database to a specific point captured by the existing backups.&lt;/p&gt;
&lt;h2&gt;
  
  
  🎯 RPO and RTO: The Two Pillars of a Solid Backup/Restore Strategy
&lt;/h2&gt;

&lt;p&gt;When talking about business continuity and disaster recovery, two concepts are &lt;strong&gt;essential to understand&lt;/strong&gt; before even considering backups or tools like Barman:&lt;/p&gt;
&lt;h3&gt;
  
  
  📌 Recovery Point Objective (RPO)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RPO&lt;/strong&gt;, or &lt;strong&gt;Recovery Point Objective&lt;/strong&gt;, represents the &lt;strong&gt;maximum amount of data you can afford to lose&lt;/strong&gt; in case of an incident.&lt;/p&gt;

&lt;p&gt;👉 Example:&lt;br&gt;&lt;br&gt;
If you can accept losing &lt;strong&gt;up to 5 minutes of data&lt;/strong&gt;, your RPO is 5 minutes. This means your backups (or WAL captures) should occur &lt;strong&gt;at least every 5 minutes&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⏱ Recovery Time Objective (RTO)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RTO&lt;/strong&gt;, or &lt;strong&gt;Recovery Time Objective&lt;/strong&gt;, represents the &lt;strong&gt;maximum acceptable downtime&lt;/strong&gt; after an incident.&lt;/p&gt;

&lt;p&gt;👉 Example:&lt;br&gt;&lt;br&gt;
If you consider a &lt;strong&gt;30 minutes service outage acceptable&lt;/strong&gt;, your RTO is 30 minutes. This means your tools and restoration mechanisms (like Barman and your automations) must be able to &lt;strong&gt;restore and bring the service online within this timeframe&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚖️ Finding the Right Balance Between Ideal and Reality
&lt;/h3&gt;

&lt;p&gt;We’d all love &lt;strong&gt;RPO = 0&lt;/strong&gt; (no data loss) and &lt;strong&gt;RTO = 0&lt;/strong&gt; (no downtime).&lt;br&gt;&lt;br&gt;
But in real life, there’s usually a &lt;strong&gt;trade-off between cost and service criticality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For a brochure website, an RPO/RTO of several hours may be acceptable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For a banking application, every second counts: RPO/RTO must be near zero.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  💡 RPO and RTO with PostgreSQL and Barman
&lt;/h3&gt;

&lt;p&gt;Good news: with a well-configured open-source stack, you can get very good performance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RPO = 0&lt;/strong&gt; 🎯&lt;br&gt;&lt;br&gt;
Thanks to PostgreSQL’s &lt;strong&gt;synchronous streaming replication&lt;/strong&gt;, your data can be protected without loss.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimal RTO&lt;/strong&gt; ⏱&lt;br&gt;&lt;br&gt;
By combining &lt;strong&gt;Barman&lt;/strong&gt; for backups and &lt;strong&gt;repmgr&lt;/strong&gt; for high availability, near-instant recovery is possible in case of issues.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧰 Prerequisites for PITR Restoration
&lt;/h3&gt;

&lt;p&gt;Before attempting a point-in-time restore, some elements must be in place for a smooth process:&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Valid backup available&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You must have at least one full backup in Barman. This will serve as the starting point for restoration.&lt;/p&gt;

&lt;p&gt;2. &lt;strong&gt;WAL archiving enabled&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
PITR relies on replaying WALs (Write Ahead Logs) up to a precise moment. Ensure archiving works correctly and files are present in Barman’s &lt;code&gt;wals&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;3. &lt;strong&gt;Sufficient disk space&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Restoration will create a new copy of the database. Ensure there is enough free space on the target server.&lt;/p&gt;

&lt;p&gt;4. &lt;strong&gt;Timestamp or XID for restoration&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To trigger PITR, specify the &lt;strong&gt;restore point&lt;/strong&gt;, either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;a date/time (&lt;code&gt;'2025-04-11 16:00:00'&lt;/code&gt;),&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a transaction ID (XID),&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;or simply the end of the backup (if you don’t replay WALs).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5. &lt;strong&gt;Test environment (optional but recommended)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Before restoring in production, it’s strongly recommended to &lt;strong&gt;test the restore&lt;/strong&gt; in an isolated environment.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔄 Data Recovery with Barman (Practical Example)
&lt;/h2&gt;

&lt;p&gt;Let’s create a table in our &lt;code&gt;test&lt;/code&gt; databas&lt;/p&gt;

&lt;p&gt;e and make several manipulations to test our backup system. Here’s a script you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- create articles table
CREATE TABLE articles (
  id SERIAL PRIMARY KEY,
  title TEXT,
  content TEXT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

--- insert 20 rows into articles table
INSERT INTO articles (title, content)
SELECT
  'Article title ' || i,
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
   Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
   Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
FROM generate_series(1, 20) AS s(i);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, take an incremental backup before simulating a data loss (e.g., accidental deletion) using &lt;code&gt;barman backup pg&lt;/code&gt; (assuming &lt;code&gt;pg&lt;/code&gt; is your PostgreSQL server in Barman’s config):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on the barman server&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;barman backup pg
Starting backup using rsync-concurrent method &lt;span class="k"&gt;for &lt;/span&gt;server pg &lt;span class="k"&gt;in&lt;/span&gt; /var/lib/barman/pg/base/20250415T201516
Backup start at LSN: 0/14000028 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000014, 00000028&lt;span class="o"&gt;)&lt;/span&gt;
Starting backup copy via rsync/SSH &lt;span class="k"&gt;for &lt;/span&gt;20250415T201516
Copy &lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;: 2 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Asking PostgreSQL server to finalize the backup.
Backup size: 38.9 MiB. Actual size on disk: 4.8 MiB &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-87&lt;/span&gt;.55% deduplication ratio&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Backup end at LSN: 0/14000100 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000014, 00000100&lt;span class="o"&gt;)&lt;/span&gt;
Backup completed &lt;span class="o"&gt;(&lt;/span&gt;start &lt;span class="nb"&gt;time&lt;/span&gt;: 2025-04-15 20:15:16.336556, elapsed &lt;span class="nb"&gt;time&lt;/span&gt;: 4 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Processing xlog segments from file archival &lt;span class="k"&gt;for &lt;/span&gt;pg
    000000010000000000000013
    000000010000000000000014
    000000010000000000000014.00000028.backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note the backup end time&lt;/strong&gt;, which will be used to set your &lt;code&gt;--target-time&lt;/code&gt; during restoration.&lt;/p&gt;

&lt;p&gt;Now, simulate data loss:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- delete articles with even IDs
DELETE FROM articles WHERE id % 2 = 0;

--- verify deletion
SELECT COUNT(id) FROM articles;

/*
--------------------------------------------
                OUTPUT
--------------------------------------------
*/
 count 
-------
    10
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💥 All articles with even IDs are now deleted. This is the perfect moment to use &lt;strong&gt;incremental recovery&lt;/strong&gt; and revert to the original state. First, take a new backup and stop the PostgreSQL server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# on the barman server&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;barman backup pg
Starting backup using rsync-concurrent method &lt;span class="k"&gt;for &lt;/span&gt;server pg &lt;span class="k"&gt;in&lt;/span&gt; /var/lib/barman/pg/base/20250415T201754
Backup start at LSN: 0/17000028 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000017, 00000028&lt;span class="o"&gt;)&lt;/span&gt;
Starting backup copy via rsync/SSH &lt;span class="k"&gt;for &lt;/span&gt;20250415T201754
Copy &lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;: 2 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Asking PostgreSQL server to finalize the backup.
Backup size: 38.9 MiB. Actual size on disk: 129.7 KiB &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-99&lt;/span&gt;.67% deduplication ratio&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Backup end at LSN: 0/17000100 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000017, 00000100&lt;span class="o"&gt;)&lt;/span&gt;
Backup completed &lt;span class="o"&gt;(&lt;/span&gt;start &lt;span class="nb"&gt;time&lt;/span&gt;: 2025-04-15 20:17:55.167843, elapsed &lt;span class="nb"&gt;time&lt;/span&gt;: 4 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Processing xlog segments from file archival &lt;span class="k"&gt;for &lt;/span&gt;pg
    000000010000000000000016
    000000010000000000000017
    000000010000000000000017.00000028.backup

&lt;span class="nv"&gt;$ &lt;/span&gt;barman list-backup pg
pg 20250415T201754 - Tue Apr 15 20:17:58 2025 - Size: 54.9 MiB - WAL Size: 0 B
pg 20250415T201516 - Tue Apr 15 20:15:19 2025 - Size: 54.9 MiB - WAL Size: 48.0 MiB
pg 20250413T113210 - Sun Apr 13 11:32:14 2025 - Size: 54.8 MiB - WAL Size: 32.0 MiB

&lt;span class="c"&gt;# on the PostgreSQL server&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;service postgresql stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two backups surround the incident: &lt;code&gt;20250415T201516&lt;/code&gt; and &lt;code&gt;20250415T201754&lt;/code&gt;. The first one (pre-incident) will be used for &lt;strong&gt;PITR&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To restore, run this command on the Barman server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman recover &lt;span class="nt"&gt;--remote-ssh-command&lt;/span&gt; &lt;span class="s2"&gt;"ssh postgres@192.168.58.11"&lt;/span&gt; &lt;span class="nt"&gt;--target-time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2025-04-15 20:17:58.270833+00:00"&lt;/span&gt; pg 20250415T201754 /var/lib/postgresql/12/main
Starting remote restore &lt;span class="k"&gt;for &lt;/span&gt;server pg using backup 20250415T201754
Destination directory: /var/lib/postgresql/12/main
Remote &lt;span class="nb"&gt;command&lt;/span&gt;: ssh postgres@192.168.58.11
Doing PITR. Recovery target &lt;span class="nb"&gt;time&lt;/span&gt;: &lt;span class="s1"&gt;'2025-04-15 20:17:58.270833+00:00'&lt;/span&gt;
Using safe horizon &lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;smart rsync copy: 2025-04-15 20:17:54.690087+00:00
Copying the base backup.
Copying required WAL segments.
Generating recovery configuration
Identify dangerous settings &lt;span class="k"&gt;in &lt;/span&gt;destination directory.

IMPORTANT
These settings have been modified to prevent data losses

postgresql.conf line 755: archive_command &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false

&lt;/span&gt;WARNING
You are required to review the following options as potentially dangerous

postgresql.conf line 41: data_directory &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/var/lib/postgresql/12/main'&lt;/span&gt;     &lt;span class="c"&gt;# use data in another directory&lt;/span&gt;
postgresql.conf line 43: hba_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/etc/postgresql/12/main/pg_hba.conf'&lt;/span&gt;   &lt;span class="c"&gt;# host-based authentication file&lt;/span&gt;
postgresql.conf line 45: ident_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/etc/postgresql/12/main/pg_ident.conf'&lt;/span&gt;   &lt;span class="c"&gt;# ident configuration file&lt;/span&gt;
postgresql.conf line 49: external_pid_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/var/run/postgresql/12-main.pid'&lt;/span&gt;          &lt;span class="c"&gt;# write an extra PID file&lt;/span&gt;
postgresql.conf line 66: unix_socket_directories &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/var/run/postgresql'&lt;/span&gt;    &lt;span class="c"&gt;# comma-separated list of directories&lt;/span&gt;
postgresql.conf line 102: ssl_cert_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/etc/ssl/certs/ssl-cert-snakeoil.pem'&lt;/span&gt;
postgresql.conf line 104: ssl_key_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/etc/ssl/private/ssl-cert-snakeoil.key'&lt;/span&gt;
postgresql.conf line 740: include_dir &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'conf.d'&lt;/span&gt;            &lt;span class="c"&gt;# include files ending in '.conf' from&lt;/span&gt;

Recovery completed &lt;span class="o"&gt;(&lt;/span&gt;start &lt;span class="nb"&gt;time&lt;/span&gt;: 2025-04-16 15:14:41.903013, elapsed &lt;span class="nb"&gt;time&lt;/span&gt;: 8 seconds&lt;span class="o"&gt;)&lt;/span&gt;

Your PostgreSQL server has been successfully prepared &lt;span class="k"&gt;for &lt;/span&gt;recovery!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Command options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--remote-ssh-command&lt;/code&gt;: SSH command to connect to the PostgreSQL server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--target-time&lt;/code&gt;: date/time to restore the data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;server_name&lt;/code&gt;: name of the server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;backup_id&lt;/code&gt;: backup to use&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;destination_directory&lt;/code&gt;: folder for restoration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Restoration can be done in any folder other than PostgreSQL’s main directory if you reconfigure PostgreSQL to point to it. After recovery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- verify data count
SELECT COUNT(id) FROM articles;

/*
--------------------------------------------
                OUTPUT
--------------------------------------------
*/
 count 
-------
    20
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  🏁 Conclusion
&lt;/h1&gt;

&lt;p&gt;Human errors, software corruption, or hardware failures are not a matter of &lt;em&gt;if&lt;/em&gt;, but &lt;em&gt;when&lt;/em&gt;. In this context, the ability to &lt;strong&gt;revert PostgreSQL to a precise previous state&lt;/strong&gt; is essential.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;Barman&lt;/strong&gt; and &lt;strong&gt;Point-In-Time Recovery (PITR)&lt;/strong&gt;, you have a reliable, robust, and powerful tool to ensure &lt;strong&gt;business continuity&lt;/strong&gt;. By combining full backups with archived WAL files, you can restore your database to the exact second before an incident.&lt;/p&gt;

&lt;p&gt;Moreover, as you’ve seen, this process can be automated, tested, and industrialized, offering a lot of advantages for enhancing your PostgreSQL architecture’s resilience.&lt;/p&gt;

</description>
      <category>backup</category>
      <category>database</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Setting up incremental backups with PostgreSql - Implementation - Part 2</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Sat, 13 Sep 2025 11:19:15 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/setting-up-incremental-backups-with-postgresql-implementation-part-2-2kmg</link>
      <guid>https://dev.to/trinitezinsou/setting-up-incremental-backups-with-postgresql-implementation-part-2-2kmg</guid>
      <description>&lt;h2&gt;
  
  
  🧭 Introduction
&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="https://trinitezinsou.hashnode.dev/sauvegardes-incrementales-postgresql-part1" rel="noopener noreferrer"&gt;first part&lt;/a&gt;, we laid the foundation: understanding the different types of backups, the crucial role of WAL files, and what Barman has to offer. Now, it’s time to take action.&lt;/p&gt;

&lt;p&gt;In this hands-on guide, we’ll &lt;strong&gt;configure PostgreSQL and Barman step by step&lt;/strong&gt; to set up a robust and automated incremental backup system. The goal is simple: you should be able to replicate it in your own environment.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️ This article uses &lt;strong&gt;Ubuntu&lt;/strong&gt; as the reference environment.&lt;/p&gt;

&lt;p&gt;We’ll use two Ubuntu 22 servers named &lt;code&gt;pg&lt;/code&gt; and &lt;code&gt;barman&lt;/code&gt;, with respective IPs: 192.168.58.11 (PostgreSQL) and 192.168.58.12 (Barman).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ready? Let’s dive in. 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Which Backup Strategy Should You Choose with Barman?
&lt;/h2&gt;

&lt;p&gt;Choosing the right backup strategy is key to building a reliable system. Barman supports two main methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Via&lt;/strong&gt; &lt;code&gt;rsync&lt;/code&gt;: a classic method using SSH to transfer files from the PostgreSQL server to the Barman server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Via&lt;/strong&gt; &lt;code&gt;pg_basebackup&lt;/code&gt;: a more modern approach using PostgreSQL’s native streaming replication protocol.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since incremental backups with &lt;code&gt;pg_basebackup&lt;/code&gt; are only supported starting with PostgreSQL 17, we’ll configure our setup using &lt;code&gt;rsync&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The diagram below illustrates how to set up incremental backups with &lt;code&gt;rsync&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fumoecnp6wb3uyy96jxgv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fumoecnp6wb3uyy96jxgv.png" alt="Incremental Backup with rsync" width="501" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To succeed with this configuration, we need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A standard connection to PostgreSQL (1)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Used by Barman for &lt;strong&gt;management, coordination, and monitoring&lt;/strong&gt; tasks. This is a classic TCP/IP connection on PostgreSQL’s port.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SSH connection for base backups (2)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Since we’re using &lt;code&gt;rsync&lt;/code&gt;, Barman must use &lt;strong&gt;SSH to connect to the PostgreSQL server&lt;/strong&gt;. The &lt;code&gt;barman&lt;/code&gt; user (on the Barman server) connects as &lt;code&gt;postgres&lt;/code&gt; (on the PostgreSQL server) to access backup files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SSH connection for WAL archiving (3)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The &lt;code&gt;archive_command&lt;/code&gt; in PostgreSQL (we’ll get to that 😉) triggers the PostgreSQL server to initiate an &lt;strong&gt;SSH connection&lt;/strong&gt;. The &lt;code&gt;postgres&lt;/code&gt; user (on the PostgreSQL server) connects as &lt;code&gt;barman&lt;/code&gt; (on the Barman server) to send the WAL files.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔑 SSH Configuration Between Barman and PostgreSQL
&lt;/h2&gt;

&lt;p&gt;To ensure secure, passwordless communication between PostgreSQL and Barman, we must set up SSH key authentication between the two servers.&lt;/p&gt;

&lt;p&gt;We'll generate SSH key pairs for both &lt;code&gt;postgres&lt;/code&gt; and &lt;code&gt;barman&lt;/code&gt; users and exchange them accordingly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the PostgreSQL server:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su postgres
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 2048
ssh-copy-id &lt;span class="nt"&gt;-i&lt;/span&gt; /var/lib/postgresql/.ssh/id_rsa barman@192.168.58.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 Make sure both &lt;code&gt;postgres&lt;/code&gt; and &lt;code&gt;barman&lt;/code&gt; have strong passwords set beforehand.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 PostgreSQL Configuration for Incremental Backups (via rsync)
&lt;/h2&gt;

&lt;p&gt;Before Barman can operate, we need to prepare PostgreSQL to provide the necessary &lt;strong&gt;WAL (Write-Ahead Log) files&lt;/strong&gt; stored in &lt;code&gt;/var/lib/postgresql/&amp;lt;version&amp;gt;/main/pg_wal/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🗂️ Enable WAL Archiving in &lt;code&gt;postgresql.conf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Open the &lt;code&gt;postgresql.conf&lt;/code&gt; file (usually located in &lt;code&gt;/etc/postgresql/&amp;lt;version&amp;gt;/main&lt;/code&gt;) and locate:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;include_dir = 'conf.d'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This allows us to create a custom config file like &lt;code&gt;archivage.conf&lt;/code&gt; inside &lt;code&gt;conf.d&lt;/code&gt;. Add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bashCopierModifierlisten_addresses &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'*'&lt;/span&gt;
wal_level &lt;span class="o"&gt;=&lt;/span&gt; replica
archive_mode &lt;span class="o"&gt;=&lt;/span&gt; on
archive_command &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'rsync -a %p barman@192.168.58.12:/var/lib/barman/pg/incoming/%f'&lt;/span&gt;
max_wal_senders &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;wal_level = replica&lt;/code&gt;: Enables WAL logging needed for replication and backups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;archive_mode = on&lt;/code&gt;: Activates archiving of WAL files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;archive_command&lt;/code&gt;: Command executed for every new WAL segment here using &lt;code&gt;rsync&lt;/code&gt; to send it to the Barman server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;max_wal_senders&lt;/code&gt;: Sets how many connections can send WALs concurrently.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ &lt;strong&gt;Tip&lt;/strong&gt;: Test your &lt;code&gt;rsync&lt;/code&gt; command manually between servers to confirm connectivity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  🔐 Allow Barman Connections in &lt;code&gt;pg_hba.conf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;/etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf&lt;/code&gt;, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Backup access&lt;/span&gt;
host    replication     barman     192.168.58.12/32      md5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create the &lt;code&gt;barman&lt;/code&gt; user in PostgreSQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;createuser &lt;span class="nt"&gt;--superuser&lt;/span&gt; &lt;span class="nt"&gt;--replication&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; barman
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Restart PostgreSQL&lt;/strong&gt; to apply changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Barman Configuration for Incremental Backups
&lt;/h2&gt;

&lt;p&gt;Now that PostgreSQL is sending WAL files, let’s configure &lt;strong&gt;Barman&lt;/strong&gt; to receive and manage them.&lt;/p&gt;

&lt;h3&gt;
  
  
  📁 Set Up the Backup Directory
&lt;/h3&gt;

&lt;p&gt;By default, Barman uses &lt;code&gt;/var/lib/barman&lt;/code&gt;. Let’s prepare a directory for our server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/lib/barman/pg
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; barman:barman /var/lib/barman/pg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧾 &lt;code&gt;barman.conf&lt;/code&gt; Configuration
&lt;/h3&gt;

&lt;p&gt;Global config: &lt;code&gt;/etc/barman.conf&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Per-server config: &lt;code&gt;/etc/barman.d/pg.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here’s a minimal config example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;pg]
description &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Primary PostgreSQL server"&lt;/span&gt;
conninfo &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;192.168.58.11 &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;barman &lt;span class="nv"&gt;dbname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test_db
ssh_command &lt;span class="o"&gt;=&lt;/span&gt; ssh postgres@192.168.58.11
backup_method &lt;span class="o"&gt;=&lt;/span&gt; rsync
streaming_archiver &lt;span class="o"&gt;=&lt;/span&gt; on
slot_name &lt;span class="o"&gt;=&lt;/span&gt; barman
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Options&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;conninfo&lt;/code&gt;: Connection string to PostgreSQL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ssh_command&lt;/code&gt;: SSH access via &lt;code&gt;postgres&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;backup_method&lt;/code&gt;: &lt;code&gt;rsync&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;streaming_archiver&lt;/code&gt;: Enables real-time WAL capture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;slot_name&lt;/code&gt;: Replication slot name for WAL streaming&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚙️ Optional Advanced Settings
&lt;/h3&gt;

&lt;p&gt;You can customize your setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iniCopierModifierreuse_backup &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;link
&lt;/span&gt;retention_policy &lt;span class="o"&gt;=&lt;/span&gt; RECOVERY WINDOW OF 7 DAYS
compression &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;gzip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;reuse_backup = link&lt;/code&gt;: Avoids file duplication&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;retention_policy&lt;/code&gt;: Keep backups for 7 days&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;compression&lt;/code&gt;: Saves disk space with gzip&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📌 Full config options available in &lt;a href="https://pgbarman.org/documentation/" rel="noopener noreferrer"&gt;Barman's documentation&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Store Passwords in &lt;code&gt;.pgpass&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To enable passwordless &lt;code&gt;conninfo&lt;/code&gt; logins, add a &lt;code&gt;.pgpass&lt;/code&gt; file for &lt;code&gt;barman&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bashCopierModifiersu barman
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt;&amp;gt;~/.pgpass
mon_serveur:5432:test_db:barman:password
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;0600 ~/.pgpass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Format:&lt;br&gt;&lt;br&gt;
&lt;code&gt;[host]:[port]:[database]:[user]:[password]&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ✅ Check That Everything Works
&lt;/h2&gt;

&lt;p&gt;Now test the Barman-PostgreSQL connection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman check pg
  Server pg:
  PostgreSQL: OK
  ...
  continuous archiving: OK
  archiver errors: OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🚀 Run Your First Backup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman backup pg
Starting backup using rsync...
Backup completed
WAL segments processed:
  000000010000000000000011
  000000010000000000000012
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔁 Automate Incremental Backups with Barman
&lt;/h2&gt;

&lt;p&gt;Use &lt;strong&gt;cron&lt;/strong&gt; to automate regular backups.&lt;/p&gt;

&lt;h3&gt;
  
  
  🕒 Schedule a Daily Backup at 2 AM
&lt;/h3&gt;

&lt;p&gt;Edit Barman's crontab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; barman crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;0 2 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; barman backup pg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 Always test your command manually before automating.&lt;/p&gt;

&lt;h3&gt;
  
  
  📉 Optimize Disk Space
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enable compression: &lt;code&gt;compression = gzip&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use retention policy: &lt;code&gt;retention_policy = RECOVERY WINDOW OF 7 DAYS&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔍 Monitor and Manage Backups with Barman
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ List Available Backups
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman list-backup pg
pg 20250415T201754 - Size: 54.9 MiB - WAL Size: 16.0 MiB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📊 Check Server Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman check pg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔎 Inspect a Specific Backup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman show-backup pg 20250415T201754
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧯 What If Something Fails?
&lt;/h2&gt;

&lt;p&gt;If a backup fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Run &lt;code&gt;barman check&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check logs in &lt;code&gt;/var/log/postgresql&lt;/code&gt; and &lt;code&gt;/var/log/barman/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏁 Conclusion: Stay in Control of Your PostgreSQL Backups
&lt;/h2&gt;

&lt;p&gt;In this second part, we focused on the &lt;strong&gt;technical setup&lt;/strong&gt; required to build a solid incremental backup strategy using Barman. From PostgreSQL tuning and secure SSH keys to cron automation and proactive monitoring—each step boosts the &lt;strong&gt;resilience&lt;/strong&gt; of your data.&lt;/p&gt;

&lt;p&gt;Barman is a &lt;strong&gt;powerful&lt;/strong&gt;, &lt;strong&gt;flexible&lt;/strong&gt;, and &lt;strong&gt;open source&lt;/strong&gt; solution that meets the needs of even the most demanding environments. But backup mastery doesn’t stop here.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://trinitezinsou.hashnode.dev/configurer-des-sauvegardes-incrementales-avec-postgresql-restauration-partie-3" rel="noopener noreferrer"&gt;next part&lt;/a&gt;, we’ll learn how to &lt;strong&gt;restore a PostgreSQL database&lt;/strong&gt;, including &lt;strong&gt;Point-In-Time Recovery (PITR)&lt;/strong&gt; and practical recovery scenarios.&lt;/p&gt;

&lt;p&gt;👉 Stay tuned to complete your PostgreSQL backup strategy!&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>postgres</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>Setting up incremental backups with PostgreSql - Introduction - Part 1</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Sat, 13 Sep 2025 11:18:40 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/setting-up-incremental-backups-with-postgresql-introduction-part-1-4l9k</link>
      <guid>https://dev.to/trinitezinsou/setting-up-incremental-backups-with-postgresql-introduction-part-1-4l9k</guid>
      <description>&lt;h2&gt;
  
  
  🧭 Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt; is a robust, reliable, and widely used database management system in the development world. It adheres to SQL standards, is open source, and most importantly, it keeps our data safe.&lt;/p&gt;

&lt;p&gt;But even the best tool can't protect you from a bad command, a bug, or a server crash. That’s where our best ally comes in: &lt;strong&gt;the backup&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll explore &lt;strong&gt;how to configure incremental backups on PostgreSQL&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
The goal? Whether you're a developer, administrator, student, or just curious, you'll be able to &lt;strong&gt;set up an automatic, efficient, and reassuring backup system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here’s what we’ll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Understanding what a backup is (and what an incremental backup means 🧠)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Discovering PostgreSQL’s built-in tools 🔧&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Step-by-step configuration of an incremental backup system 🛠️&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automating the process with scripts and &lt;code&gt;cron&lt;/code&gt; ⏰&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And even testing restoration (because an untested backup is just an illusion of safety 😉)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ready? Let’s start with the basics. 👇&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 Reminder: What’s a backup (and what’s an incremental one)?
&lt;/h2&gt;

&lt;p&gt;Before jumping into the configuration, let’s take a moment to lay the groundwork because good understanding is already half the job.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔐 What is a backup?
&lt;/h3&gt;

&lt;p&gt;It’s simply a &lt;strong&gt;copy of data&lt;/strong&gt; (files, databases, configurations, etc.) stored &lt;strong&gt;separately&lt;/strong&gt;, in a safe place, so we can &lt;strong&gt;recover it if something goes wrong&lt;/strong&gt;: human error, failure, hacking or just a “Oops, I deleted everything.”&lt;/p&gt;
&lt;h3&gt;
  
  
  🧱 The 3 main types of backups
&lt;/h3&gt;

&lt;p&gt;There are several ways to back up data. Here are the three most common:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Full backup&lt;/strong&gt;: you copy &lt;strong&gt;all files&lt;/strong&gt; every time. It’s simple but can quickly become heavy on disk space.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Differential backup&lt;/strong&gt;: you copy only files that have changed &lt;strong&gt;since the last full backup&lt;/strong&gt;. It's lighter, but over time it accumulates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Incremental backup&lt;/strong&gt;: you copy files that have changed &lt;strong&gt;since the last backup whatever type it was&lt;/strong&gt; (full or incremental). It’s the most optimized in terms of size and time but a bit more technical to manage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  📌 Why are incremental backups great?
&lt;/h3&gt;

&lt;p&gt;Because they help you &lt;strong&gt;save time and space&lt;/strong&gt; while keeping a history of changes. And the good news is: PostgreSQL supports this kind of backup thanks to a built-in mechanism called &lt;strong&gt;Write-Ahead Logging&lt;/strong&gt; (&lt;a href="https://www.postgresql.org/docs/current/wal-intro.html" rel="noopener noreferrer"&gt;&lt;strong&gt;WAL&lt;/strong&gt;&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;👉 That’s exactly what we’ll use in this guide.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔍 How does PostgreSQL handle incremental backups?
&lt;/h2&gt;

&lt;p&gt;Let’s start by reviewing the types of backups PostgreSQL offers so we can understand the available mechanisms before diving into incremental backups.&lt;/p&gt;
&lt;h3&gt;
  
  
  🧬 The different types of backups in PostgreSQL
&lt;/h3&gt;

&lt;p&gt;PostgreSQL offers three backup options 👇:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Full backup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This consists of copying the entire database at a specific point in time. It’s a &lt;strong&gt;&lt;em&gt;snapshot&lt;/em&gt;&lt;/strong&gt; of the database and allows restoration to its exact state when the backup was taken. Tools like &lt;a href="https://www.postgresql.org/docs/current/app-pgbasebackup.html" rel="noopener noreferrer"&gt;&lt;code&gt;pg_basebackup&lt;/code&gt;&lt;/a&gt; or manual file copying can be used for this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Logical backup (&lt;/strong&gt;&lt;code&gt;pg_dump&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;This uses the &lt;a href="https://www.postgresql.org/docs/current/app-pgdump.html" rel="noopener noreferrer"&gt;&lt;code&gt;pg_dump&lt;/code&gt;&lt;/a&gt; tool to export the database as an SQL script. It’s a form of full backup that lets you recover the database independently of PostgreSQL’s physical structure. It’s often used for migrations or targeted backups (e.g., a table or schema). However, it has limitations for incremental backups, as it doesn’t include WAL transaction logs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Incremental backup (WAL-based)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;incremental backup&lt;/strong&gt; only saves changes made since the last backup (whether full or incremental). It relies on archiving &lt;strong&gt;WAL (Write-Ahead Log)&lt;/strong&gt; files generated by PostgreSQL. These files record every transaction applied to the database. Using them, you can restore the database to a precise moment in time achieving a very low &lt;a href="https://www.acronis.com/en-us/blog/posts/rto-rpo/" rel="noopener noreferrer"&gt;&lt;strong&gt;RPO&lt;/strong&gt;&lt;/a&gt; (Recovery Point Objective), often just a few minutes. This is about minimizing the amount of data you are willing to lose after an incident.&lt;/p&gt;
&lt;h3&gt;
  
  
  🧪 About incremental backups
&lt;/h3&gt;

&lt;p&gt;PostgreSQL’s key feature for incremental backups is &lt;strong&gt;Write-Ahead Logging (WAL)&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Each write operation on the database is logged in special log files. These files record changes to the database before they are actually applied, thus ensuring data integrity.&lt;br&gt;&lt;br&gt;
This mechanism, known as &lt;strong&gt;WAL&lt;/strong&gt;, makes it possible to &lt;strong&gt;restore the state of the database at a specific point in time&lt;/strong&gt;, a technique called &lt;a href="https://en.wikipedia.org/wiki/Point-in-time_recovery" rel="noopener noreferrer"&gt;Point In Time Recovery (PITR)&lt;/a&gt;. This means that after an initial full backup, you can restore a database to any given moment by replaying the WAL files generated since that backup.&lt;br&gt;&lt;br&gt;
That’s exactly what we’re going to leverage in our configuration with &lt;strong&gt;Barman&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚙️ How WAL works
&lt;/h3&gt;

&lt;p&gt;When WAL archiving is enabled, PostgreSQL generates log files in a specific directory (&lt;code&gt;/var/lib/postgresql/{version}/main/pg_wal/&lt;/code&gt;) with each write operation. These files are rotated once they reach &lt;strong&gt;16 MB&lt;/strong&gt; (by default).&lt;br&gt;&lt;br&gt;
Each time a WAL file is created or modified, PostgreSQL can run a &lt;strong&gt;custom command&lt;/strong&gt;, allowing centralized WAL archiving and simplified recovery.&lt;/p&gt;

&lt;p&gt;Barman leverages these WAL files to manage incremental backups and point-in-time restores.&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 What is Barman?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  🍹 Introducing Barman
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Barman&lt;/strong&gt; (Backup and Recovery Manager) is a Python-based tool that simplifies backup and recovery operations for PostgreSQL.&lt;br&gt;&lt;br&gt;
It helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Scheduling and automating backups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Managing full and incremental backups&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performing &lt;strong&gt;Point-In-Time Recovery (PITR)&lt;/strong&gt; using WAL files&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s especially useful for managing multiple PostgreSQL servers and centralizing backup/restoration operations.&lt;/p&gt;

&lt;p&gt;We’ll be configuring and using this tool in this article.&lt;/p&gt;
&lt;h3&gt;
  
  
  🤔 Barman vs &lt;code&gt;pg_dump&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Before going further, let’s compare &lt;strong&gt;Barman&lt;/strong&gt; with traditional PostgreSQL backup tools: &lt;strong&gt;pg_dump&lt;/strong&gt; / &lt;strong&gt;pg_basebackup&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pg_dump&lt;/strong&gt; / &lt;strong&gt;pg_basebackup&lt;/strong&gt;: These tools perform full backups, exporting the database’s state (as an SQL script, for example). However, they are limited when it comes to fast disaster recovery, since they only restore the &lt;strong&gt;exact point in time&lt;/strong&gt; when the backup was made.&lt;br&gt;&lt;br&gt;
Let’s say you run a nightly &lt;code&gt;pg_dump&lt;/code&gt; at 3 AM, and an incident happens at 6 PM. You’d lose all changes made since 3 AM &lt;strong&gt;15 hours of data loss&lt;/strong&gt;, which is unacceptable in most business scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Barman&lt;/strong&gt;: Unlike &lt;code&gt;pg_dump&lt;/code&gt;, Barman &lt;strong&gt;works at the physical level&lt;/strong&gt;. It handles &lt;strong&gt;full and incremental&lt;/strong&gt; backups, using WAL files to recover any change since the last backup. This allows &lt;strong&gt;low RPOs&lt;/strong&gt;, minimizing data loss to a few minutes.&lt;br&gt;&lt;br&gt;
Of course, it requires more disk space, but the tradeoff is well worth it for data security and recovery capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  📦 Installing Barman
&lt;/h3&gt;

&lt;p&gt;Before using &lt;strong&gt;Barman&lt;/strong&gt;, make sure PostgreSQL is properly installed.&lt;br&gt;&lt;br&gt;
Ubuntu users can follow &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-22-04" rel="noopener noreferrer"&gt;this tutorial&lt;/a&gt;, and CentOS/RHEL users can refer to &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-centos-8" rel="noopener noreferrer"&gt;this one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once PostgreSQL is ready, we’ll look into advanced configuration. But first, let’s install Barman:&lt;/p&gt;
&lt;h4&gt;
  
  
  a. &lt;strong&gt;On Ubuntu/Debian&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;On Debian-based systems like &lt;strong&gt;Ubuntu&lt;/strong&gt;, install Barman from official repositories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install from the repository&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;barman
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Check the installation&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Once installation is complete, check that Barman has been installed correctly by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;barman
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ol&gt;

&lt;h4&gt;
  
  
  a. &lt;strong&gt;On Ubuntu/Debian&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;On CentOS or RHEL, you must first add the official Barman repository before installing it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the barman official repository&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; https://dl.enterprisedb.com/barman/barman-2.16.0-1.rhel7.x86_64.rpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update system packages and install Barman&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum update
 &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;barman
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check the barman installation&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;barman &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🧾 Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this article, we explored the fundamental concepts needed to implement incremental backups in PostgreSQL, with a focus on the critical role of transaction logs (WAL) and the &lt;strong&gt;PITR&lt;/strong&gt; mechanism. We also saw how &lt;strong&gt;Barman&lt;/strong&gt;, the backup and recovery management tool, fits seamlessly into this process.&lt;/p&gt;

&lt;p&gt;The goal was to provide a clear understanding of what incremental backups involve in PostgreSQL before diving into the technical configuration itself. With this foundation, you now have a broader perspective on the challenges and tools required for effective backup management.&lt;/p&gt;

&lt;p&gt;In Part 2, we’ll get into the heart of the matter with the complete configuration of Barman from installation to enabling incremental backups. We’ll also cover best practices to ensure the continuity and reliability of your backups.&lt;/p&gt;

&lt;p&gt;Stay tuned for the next article to learn how to configure and automate your backups efficiently.&lt;/p&gt;

</description>
      <category>backup</category>
      <category>postgres</category>
      <category>database</category>
    </item>
    <item>
      <title>Configurer des sauvegardes incrémentales avec PostgreSql - Introduction-Partie 3</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Sun, 29 Jun 2025 13:18:02 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-restauration-partie-3-33n3</link>
      <guid>https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-restauration-partie-3-33n3</guid>
      <description>&lt;h2&gt;
  
  
  🧭 Introduction
&lt;/h2&gt;

&lt;p&gt;Mettre en place des sauvegardes, c’est essentiel. Mais savoir les &lt;strong&gt;restaurer efficacement en cas de besoin&lt;/strong&gt;, c’est encore plus crucial. C’est ici que le &lt;strong&gt;PITR&lt;/strong&gt; (Point In Time Recovery) entre en jeu, une fonctionnalité puissante offerte par PostgreSQL et parfaitement gérée par Barman.&lt;/p&gt;

&lt;p&gt;Que ce soit pour corriger une erreur humaine, revenir avant un déploiement raté ou analyser l’état de la base à un instant précis, Barman permet de &lt;strong&gt;ramener PostgreSQL dans le passé&lt;/strong&gt;, en rejouant uniquement les modifications jusqu’à un point bien défini.&lt;/p&gt;

&lt;p&gt;Dans ce chapitre, nous allons explorer :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ce qu’est concrètement le PITR,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Les prérequis pour qu’il fonctionne,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Et surtout, &lt;strong&gt;comment l’utiliser pas à pas&lt;/strong&gt; avec Barman, de manière fiable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Prêt à voyager dans le temps avec PostgreSQL ? C’est par ici 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  🕰️ C’est quoi le PITR (Point-In-Time Recovery) ?
&lt;/h2&gt;

&lt;p&gt;Le &lt;strong&gt;Point-In-Time Recovery&lt;/strong&gt;, ou &lt;strong&gt;PITR&lt;/strong&gt;, est une fonctionnalité puissante de PostgreSQL qui permet de restaurer une base de données à &lt;strong&gt;un instant précis dans le passé&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
C’est un peu comme une machine à remonter le temps 🕳️🕒.&lt;/p&gt;

&lt;p&gt;Imaginons qu’un bug ou une erreur humaine ait corrompu des données ce matin à 10h30. Grâce au PITR, vous pouvez restaurer la base &lt;strong&gt;exactement comme elle était à 09h29&lt;/strong&gt;, juste avant le problème.&lt;/p&gt;

&lt;p&gt;Pour que cela fonctionne, PostgreSQL enregistre toutes les écriture sur la base de données dans des fichiers appelés &lt;strong&gt;WALs (Write Ahead Logs)&lt;/strong&gt;. Ces fichiers contiennent l’historique des modifications apportées à la base.&lt;br&gt;&lt;br&gt;
Barman exploite ces fichiers pour &lt;strong&gt;rejouer l’histoire de la base&lt;/strong&gt; jusqu’à l’instant choisi, à partir d’une sauvegarde complète. Il effectue ainsi un rétropédalage jusqu’à un instant désiré bien pris en compte par les sauvegardes existantes&lt;/p&gt;
&lt;h2&gt;
  
  
  🎯 RPO et RTO : Les deux piliers d’une bonne stratégie de sauvegarde/restauration
&lt;/h2&gt;

&lt;p&gt;Quand on parle de continuité d’activité et de plan de reprise après sinistre (disaster recovery), deux notions sont &lt;strong&gt;essentielles à comprendre&lt;/strong&gt; avant même de parler de sauvegarde ou d’outil comme Barman :&lt;/p&gt;
&lt;h3&gt;
  
  
  📌 Recovery Point Objective (RPO)
&lt;/h3&gt;

&lt;p&gt;Le &lt;strong&gt;RPO&lt;/strong&gt;, ou &lt;strong&gt;objectif de point de reprise&lt;/strong&gt;, représente la &lt;strong&gt;quantité maximale de données que l'on peut se permettre de perdre&lt;/strong&gt; en cas d’incident.&lt;/p&gt;

&lt;p&gt;👉 Exemple :&lt;br&gt;&lt;br&gt;
Si vous acceptez de perdre &lt;strong&gt;au maximum 5 minutes de données&lt;/strong&gt;, votre RPO est de 5 minutes. Cela implique que vos sauvegardes (ou la capture de vos WAL) doivent se faire &lt;strong&gt;au moins toutes les 5 minutes&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⏱ Recovery Time Objective (RTO)
&lt;/h3&gt;

&lt;p&gt;Le &lt;strong&gt;RTO&lt;/strong&gt;, ou &lt;strong&gt;objectif de temps de reprise&lt;/strong&gt;, désigne la &lt;strong&gt;durée maximale acceptable d’indisponibilité du service&lt;/strong&gt; après un incident.&lt;/p&gt;

&lt;p&gt;👉 Exemple :&lt;br&gt;&lt;br&gt;
Si vous estimez qu’une interruption de service de &lt;strong&gt;30 minutes est tolérable&lt;/strong&gt;, alors votre RTO est de 30 minutes. Cela implique que vos outils et mécanisme de restauration (comme Barman et les automatisations que vous mettrez en place) doivent être capables de &lt;strong&gt;restorer et remettre le service en ligne dans ce délai&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚖️ Trouver le bon équilibre entre idéal et réalité
&lt;/h3&gt;

&lt;p&gt;On aimerait tous avoir un &lt;strong&gt;RPO = 0&lt;/strong&gt; (aucune perte de données) et un &lt;strong&gt;RTO = 0&lt;/strong&gt; (aucun temps d’arrêt).&lt;br&gt;&lt;br&gt;
Mais dans la vraie vie, il faut souvent faire un &lt;strong&gt;compromis entre le coût et la criticité du service&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Par exemple :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Pour un site vitrine, un RPO/RTO de plusieurs heures peut être toléré.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pour une application bancaire, chaque seconde compte : le RPO/RTO doit être quasi nul.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  💡 RPO et RTO avec PostgreSQL et Barman
&lt;/h3&gt;

&lt;p&gt;Bonne nouvelle : avec un stack open source bien configuré, il est possible de s’approcher de très bonnes performances :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RPO = 0&lt;/strong&gt; 🎯&lt;br&gt;&lt;br&gt;
Grâce à la &lt;strong&gt;réplication en streaming synchrone&lt;/strong&gt; de PostgreSQL, vos données peuvent être protégées sans perte.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RTO minimal&lt;/strong&gt; ⏱&lt;br&gt;&lt;br&gt;
En combinant &lt;strong&gt;Barman&lt;/strong&gt; pour les sauvegardes et &lt;strong&gt;repmgr&lt;/strong&gt; pour la haute disponibilité, on peut atteindre un redémarrage quasi instantané en cas de problème.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧰 Prérequis pour une restauration avec PITR
&lt;/h3&gt;

&lt;p&gt;Avant de tenter une restauration point-in-time, quelques éléments doivent être en place pour que tout se passe bien :&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Sauvegarde valide disponible&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Vous devez avoir au moins une sauvegarde complète dans Barman. Elle servira de point de départ pour la restauration.&lt;/p&gt;

&lt;p&gt;2. &lt;strong&gt;Archivage WAL activé&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Le PITR repose sur la capacité à rejouer les WAL (Write Ahead Logs) jusqu’à un instant précis. Assurez-vous que l’archivage fonctionne correctement et que les fichiers sont bien présents dans le répertoire &lt;code&gt;wals&lt;/code&gt; de Barman.&lt;/p&gt;

&lt;p&gt;3. &lt;strong&gt;Espace disque suffisant&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
La restauration va créer une nouvelle copie de la base. Il est essentiel d’avoir suffisamment d’espace libre sur le serveur cible.&lt;/p&gt;

&lt;p&gt;4. &lt;strong&gt;Horodatage ou XID de restauration&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Pour déclencher un PITR, vous devez spécifier le &lt;strong&gt;point de restauration&lt;/strong&gt;, soit :&lt;/p&gt;

&lt;p&gt;* une date/heure (&lt;code&gt;'2025-04-11 16:00:00'&lt;/code&gt;),&lt;/p&gt;

&lt;p&gt;* un identifiant de transaction (XID),&lt;/p&gt;

&lt;p&gt;* ou simplement la fin de la sauvegarde (si vous ne rejouez pas les WAL).&lt;/p&gt;

&lt;p&gt;5. &lt;strong&gt;Environnement&lt;/strong&gt; &lt;strong&gt;de test (optionnel mais recommandé)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Avant de lancer une restauration en production, il est fortement conseillé de &lt;strong&gt;tester la restauration&lt;/strong&gt; dans un environnement isolé.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔄 Récupération des données avec Barman (cas pratique)
&lt;/h2&gt;

&lt;p&gt;Nous allons créer une table au niveau de notre base de données &lt;code&gt;test&lt;/code&gt; et faire plusieurs manipulations afin d’éprouver notre système de sauvegarde.On va donc ajouter une table à notre base de données et y ajouter quelques lignes(tu peux te servir de ce script😉):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- creation d'une table articles
CREATE TABLE articles (
  id SERIAL PRIMARY KEY,
  title TEXT,
  content TEXT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

--- insertion de 20 lignes dans la table articles

INSERT INTO articles (title, content)
SELECT
  'Titre de l’article ' || i,
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
   Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
   Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
FROM generate_series(1, 20) AS s(i);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A cette étape on va refaire une sauvegarde incrémentale de notre base donnée avant de simuler un incident, une suppression involontaire de données par exemple toujours à l’aide de la commande &lt;code&gt;barman backup pg&lt;/code&gt;(ici pg est le nom de notre serveur de base de données dans notre configuration barman), voici le retour à mon niveau:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# sur le serveur barman&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;barman backup pg
Starting backup using rsync-concurrent method &lt;span class="k"&gt;for &lt;/span&gt;server pg &lt;span class="k"&gt;in&lt;/span&gt; /var/lib/barman/pg/base/20250415T201516
Backup start at LSN: 0/14000028 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000014, 00000028&lt;span class="o"&gt;)&lt;/span&gt;
Starting backup copy via rsync/SSH &lt;span class="k"&gt;for &lt;/span&gt;20250415T201516
Copy &lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;: 2 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Asking PostgreSQL server to finalize the backup.
Backup size: 38.9 MiB. Actual size on disk: 4.8 MiB &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-87&lt;/span&gt;.55% deduplication ratio&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Backup end at LSN: 0/14000100 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000014, 00000100&lt;span class="o"&gt;)&lt;/span&gt;
Backup completed &lt;span class="o"&gt;(&lt;/span&gt;start &lt;span class="nb"&gt;time&lt;/span&gt;: 2025-04-15 20:15:16.336556, elapsed &lt;span class="nb"&gt;time&lt;/span&gt;: 4 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Processing xlog segments from file archival &lt;span class="k"&gt;for &lt;/span&gt;pg
    000000010000000000000013
    000000010000000000000014
    000000010000000000000014.00000028.backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note bien la date de fin&lt;/strong&gt; de sauvegarde (&lt;code&gt;start time+ temps ecoulé&lt;/code&gt; ou accesible avec &lt;code&gt;barman show-backup pg id_backup&lt;/code&gt; ). Elle te servira de référence pour définir ton &lt;code&gt;--target-time&lt;/code&gt; lors de la restauration.A présent simulons la perte de données:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- suppression des articles d'id pairs
DELETE FROM articles WHERE id % 2 = 0;

--- vérifier que les éléments ont bien été supprimés
SELECT COUNT(id) FROM article; 

/*
--------------------------------------------
                OUTPUT
--------------------------------------------
*/
 count 
-------
    10
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💥 Tous les articles avec un identifiant pair etant désormais supprimés (cet incident intervient peu de temps après ma dernière sauvegarde). C’est le moment idéal pour utiliser la &lt;strong&gt;récupération incrémentale&lt;/strong&gt; et revenir à l’état initial. Avant de restorer nos données nous allons refaire une nouvelle sauvegarde et arreter notre serveur postgresql:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# sur le serveur barman&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;barman backup pg
Starting backup using rsync-concurrent method &lt;span class="k"&gt;for &lt;/span&gt;server pg &lt;span class="k"&gt;in&lt;/span&gt; /var/lib/barman/pg/base/20250415T201754
Backup start at LSN: 0/17000028 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000017, 00000028&lt;span class="o"&gt;)&lt;/span&gt;
Starting backup copy via rsync/SSH &lt;span class="k"&gt;for &lt;/span&gt;20250415T201754
Copy &lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;: 2 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Asking PostgreSQL server to finalize the backup.
Backup size: 38.9 MiB. Actual size on disk: 129.7 KiB &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-99&lt;/span&gt;.67% deduplication ratio&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Backup end at LSN: 0/17000100 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000017, 00000100&lt;span class="o"&gt;)&lt;/span&gt;
Backup completed &lt;span class="o"&gt;(&lt;/span&gt;start &lt;span class="nb"&gt;time&lt;/span&gt;: 2025-04-15 20:17:55.167843, elapsed &lt;span class="nb"&gt;time&lt;/span&gt;: 4 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Processing xlog segments from file archival &lt;span class="k"&gt;for &lt;/span&gt;pg
    000000010000000000000016
    000000010000000000000017
    000000010000000000000017.00000028.backup

&lt;span class="nv"&gt;$ &lt;/span&gt;barman list-backup pg
pg 20250415T201754 - Tue Apr 15 20:17:58 2025 - Size: 54.9 MiB - WAL Size: 0 B
pg 20250415T201516 - Tue Apr 15 20:15:19 2025 - Size: 54.9 MiB - WAL Size: 48.0 MiB
pg 20250413T113210 - Sun Apr 13 11:32:14 2025 - Size: 54.8 MiB - WAL Size: 32.0 MiB

&lt;span class="c"&gt;# sur le serveur postgres&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;service postgresql stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A cette étape deux sauvegardes encadren notre incident, celles d’ids &lt;code&gt;20250415T201516&lt;/code&gt; et &lt;code&gt;20250415T201754&lt;/code&gt;. La première est celle avec d’avant incident qui nous servira donc pour notre &lt;strong&gt;PITR.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La commande de restoration à taper sur le serveur barman est la suivante:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman recover &lt;span class="nt"&gt;--remote-ssh-command&lt;/span&gt; &lt;span class="s2"&gt;"ssh postgres@192.168.58.11"&lt;/span&gt; &lt;span class="nt"&gt;--target-time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2025-04-15 20:17:58.270833+00:00"&lt;/span&gt; pg 20250415T201754 /var/lib/postgresql/12/main
Starting remote restore &lt;span class="k"&gt;for &lt;/span&gt;server pg using backup 20250415T201754
Destination directory: /var/lib/postgresql/12/main
Remote &lt;span class="nb"&gt;command&lt;/span&gt;: ssh postgres@192.168.58.11
Doing PITR. Recovery target &lt;span class="nb"&gt;time&lt;/span&gt;: &lt;span class="s1"&gt;'2025-04-15 20:17:58.270833+00:00'&lt;/span&gt;
Using safe horizon &lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;smart rsync copy: 2025-04-15 20:17:54.690087+00:00
Copying the base backup.
Copying required WAL segments.
Generating recovery configuration
Identify dangerous settings &lt;span class="k"&gt;in &lt;/span&gt;destination directory.

IMPORTANT
These settings have been modified to prevent data losses

postgresql.conf line 755: archive_command &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false

&lt;/span&gt;WARNING
You are required to review the following options as potentially dangerous

postgresql.conf line 41: data_directory &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/var/lib/postgresql/12/main'&lt;/span&gt;     &lt;span class="c"&gt;# use data in another directory&lt;/span&gt;
postgresql.conf line 43: hba_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/etc/postgresql/12/main/pg_hba.conf'&lt;/span&gt;   &lt;span class="c"&gt;# host-based authentication file&lt;/span&gt;
postgresql.conf line 45: ident_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/etc/postgresql/12/main/pg_ident.conf'&lt;/span&gt;   &lt;span class="c"&gt;# ident configuration file&lt;/span&gt;
postgresql.conf line 49: external_pid_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/var/run/postgresql/12-main.pid'&lt;/span&gt;          &lt;span class="c"&gt;# write an extra PID file&lt;/span&gt;
postgresql.conf line 66: unix_socket_directories &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/var/run/postgresql'&lt;/span&gt;    &lt;span class="c"&gt;# comma-separated list of directories&lt;/span&gt;
postgresql.conf line 102: ssl_cert_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/etc/ssl/certs/ssl-cert-snakeoil.pem'&lt;/span&gt;
postgresql.conf line 104: ssl_key_file &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/etc/ssl/private/ssl-cert-snakeoil.key'&lt;/span&gt;
postgresql.conf line 740: include_dir &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'conf.d'&lt;/span&gt;            &lt;span class="c"&gt;# include files ending in '.conf' from&lt;/span&gt;

Recovery completed &lt;span class="o"&gt;(&lt;/span&gt;start &lt;span class="nb"&gt;time&lt;/span&gt;: 2025-04-16 15:14:41.903013, elapsed &lt;span class="nb"&gt;time&lt;/span&gt;: 8 seconds&lt;span class="o"&gt;)&lt;/span&gt;

Your PostgreSQL server has been successfully prepared &lt;span class="k"&gt;for &lt;/span&gt;recovery!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Les options de cette commande sont: &lt;code&gt;--remote-ssh-command&lt;/code&gt; une commande ssh vers le serveur postgres, &lt;code&gt;--target-time&lt;/code&gt; la date à laquelle restorée les données qui doit etre xxxxxxxxxxxxxx, &lt;code&gt;server_name&lt;/code&gt; pour le nom du serveur, &lt;code&gt;backup_id&lt;/code&gt; le nom du backup et &lt;code&gt;destination_directory&lt;/code&gt; pour le dossier qui doit accepter les sauvegardes. Tu pourrais avoir plus d’options avec &lt;code&gt;barman recover -h&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;La recupération peut se faire dans n’importe quel dossier à part celui de base de postgres à condition de reconfiguer postgres pour pointer sur le dossier considéré. On peut après avoir à nouveau accès à nos données récupérées:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--- vérifier que les éléments ont bien été supprimés
SELECT COUNT(id) FROM article; 

/*
--------------------------------------------
                OUTPUT
--------------------------------------------
*/
 count 
-------
    20
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;Les erreurs humaines, les corruptions logicielles ou les incidents matériels ne sont pas une question de "si", mais de "quand". Dans ce contexte, la capacité à &lt;strong&gt;revenir à un état antérieur précis&lt;/strong&gt; de ta base PostgreSQL est essentielle.&lt;/p&gt;

&lt;p&gt;Avec &lt;strong&gt;Barman&lt;/strong&gt; et la fonctionnalité de &lt;strong&gt;Point-In-Time Recovery (PITR)&lt;/strong&gt;, tu disposes d’un outil fiable, robuste et puissant pour répondre aux impératifs de &lt;strong&gt;continuité d’activité&lt;/strong&gt;. En combinant les sauvegardes complètes aux fichiers WAL archivés, tu peux restaurer ta base à la seconde près, juste avant un incident.&lt;/p&gt;

&lt;p&gt;Plus encore, tu l’as vu : ce processus peut s’automatiser, se tester, s’industrialiser; autant d’atouts pour renforcer la résilience de ton architecture PostgreSQL.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>backup</category>
      <category>database</category>
    </item>
    <item>
      <title>Configurer des sauvegardes incrémentales avec PostgreSql - Introduction-Partie 2</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Thu, 12 Jun 2025 22:40:57 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-mise-en-place-partie-2-f6o</link>
      <guid>https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-mise-en-place-partie-2-f6o</guid>
      <description>&lt;h2&gt;
  
  
  🧭 Introduction
&lt;/h2&gt;

&lt;p&gt;Dans la &lt;a href="https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-introduction-partie-1--12i0"&gt;première partie&lt;/a&gt;, on a posé les bases : comprendre les différents types de sauvegardes, le rôle crucial des fichiers WAL et ce que propose Barman. Maintenant, il est temps de passer à l’action.&lt;/p&gt;

&lt;p&gt;Dans ce guide pratique, on va &lt;strong&gt;configurer PostgreSQL et Barman pas à pas&lt;/strong&gt; pour mettre en place un système de sauvegarde incrémentale robuste et automatisé. L’objectif est simple : que tu puisses le reproduire dans ton propre environnement.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️ L'environnement de référence utilisé dans cet article est Ubuntu&lt;/p&gt;

&lt;p&gt;Dans la suite nous utiliserons deux serveurs Ubuntu 22, qu’on appellera pg et barman pour postgres et barman respectivements et d’ip respectifs 192.168.58.11 et 192.168.58.12&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Prêt ? On entre dans le vif du sujet. 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Quelle stratégie de sauvegarde choisir avec Barman ?
&lt;/h2&gt;

&lt;p&gt;Le choix de la stratégie de sauvegarde est un élément crucial dans la mise en place d’un système fiable. Barman prend en charge deux grandes méthodes :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Via&lt;/strong&gt; &lt;code&gt;rsync&lt;/code&gt; : une méthode classique utilisant SSH pour transférer les fichiers du serveur PostgreSQL vers le serveur Barman.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Via&lt;/strong&gt; &lt;code&gt;pg_basebackup&lt;/code&gt; : une méthode moderne qui s’appuie sur le protocole de réplication en streaming natif de PostgreSQL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le streaming via &lt;code&gt;pg_basebackup&lt;/code&gt; ne permet les sauvegardes incrémentales qu’à partir de la version 17 de Postgres, nous allons donc dans la suite voir comment faire nos configurations pour effectuer nos sauvegardes via &lt;code&gt;rsync&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;La figure ci dessous illustre comment mettre en place les sauvegardes incrémentales avec &lt;code&gt;rsync&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjsk97rugfvy6foyasjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjsk97rugfvy6foyasjg.png" alt="illustration sauvegarde incrémentale" width="501" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Il nous faut donc pour réussir notre configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Une connexion standard à PostgreSQL (1)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Utilisée par Barman pour les &lt;strong&gt;opérations de gestion, de coordination et de supervision&lt;/strong&gt;. Cette connexion se fait généralement via un accès réseau classique au port PostgreSQL, souvent en TCP/IP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Connexion SSH pour les sauvegardes de base (2)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Puisque nous avons décidé d’utiliser &lt;code&gt;rsync&lt;/code&gt;, Barman doit pouvoir utiliser &lt;strong&gt;SSH pour se connecter au serveur PostgreSQL&lt;/strong&gt;. L’utilisateur &lt;code&gt;barman&lt;/code&gt; (sur le serveur Barman) doit &lt;strong&gt;se connecter en tant que&lt;/strong&gt; &lt;code&gt;postgres&lt;/code&gt; (sur le serveur PostgreSQL) et accéder aux fichiers nécessaires à la sauvegarde.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Connexion SSH pour l’archivage des fichiers WAL (3)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Pour l’archivage des WALs, une configuration appelée &lt;code&gt;archive_command&lt;/code&gt; de postgresql est activé(on en parle dans la suite 😉), et là &lt;strong&gt;le serveur PostgreSQL doit initier une connexion SSH&lt;/strong&gt;. L’utilisateur &lt;code&gt;postgres&lt;/code&gt; (du serveur PostgreSQL) va &lt;strong&gt;se connecter en SSH au serveur Barman&lt;/strong&gt;, en tant qu’utilisateur &lt;code&gt;barman&lt;/code&gt;, afin d’envoyer les fichiers WAL au bon endroit.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🔑 Configurations SSH entre Barman et PostgreSQL&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Pour permettre à Barman et PostgreSQL de communiquer de manière sécurisée et automatisée, il est essentiel de configurer une authentification par clé SSH entre les deux serveurs. Cette étape garantit des transferts fiables, sans mot de passe, pour les sauvegardes et l’archivage des fichiers WAL.&lt;/p&gt;

&lt;p&gt;On va donc générer des paires de clés ssh en tant qu’utilisateurs postgres et barman à échanger entre nos différents serveurs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sur le serveur postgres:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su postgres
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 2048
&lt;span class="c"&gt;# fichier généré par default =&amp;gt; /var/lib/postgresql/.ssh/id_rsa&lt;/span&gt;
ssh-copy-id &lt;span class="nt"&gt;-i&lt;/span&gt; /var/lib/postgresql/.ssh/id_rsa barman@192.168.58.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Sur le serveur barman:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su barman
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 2048
&lt;span class="c"&gt;# fichier généré par default =&amp;gt; /var/lib/barman/.ssh/id_rsa&lt;/span&gt;
ssh-copy-id &lt;span class="nt"&gt;-i&lt;/span&gt; /var/lib/barman/.ssh/id_rsa postgres@192.168.58.11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette étape nécessite de définir en amont pour les utilsateurs &lt;code&gt;postgres&lt;/code&gt; et &lt;code&gt;barman&lt;/code&gt; des mots de passe robustes.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 Configuration détaillée de PostgreSQL pour les sauvegardes incrémentales (avec rsync)
&lt;/h2&gt;

&lt;p&gt;Avant que Barman ne puisse faire son travail, il faut préparer PostgreSQL pour lui fournir ce dont il a besoin : &lt;strong&gt;les fichiers WAL (Write-Ahead Logs)&lt;/strong&gt;. Ces fichiers contenus dans le dossier &lt;code&gt;/var/lib/postgresql/&amp;lt;version&amp;gt;/main/pg_wal/&lt;/code&gt; contiennent un historique clair de toutes les écritures sur la base de données et sont essentiels pour effectuer des sauvegardes incrémentales.&lt;/p&gt;

&lt;p&gt;Nous allons donc commencer par activer l’archivage WAL au niveau de notre serveur PostgreSQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  🗂️ Activer l’archivage WAL dans &lt;code&gt;postgresql.conf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Ouvre ton fichier &lt;code&gt;postgresql.conf&lt;/code&gt;, généralement situé dans le répertoire principal de PostgreSQL (&lt;code&gt;/etc/postgresql/&amp;lt;version&amp;gt;/main&lt;/code&gt;), et recherche la ligne&lt;/p&gt;

&lt;p&gt;&lt;code&gt;include_dir = 'conf.d' # include files ending in '.conf' from&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Grace à cette ligne, on peut créer dans le dossier conf.d du répertoire principal, un fichier &lt;code&gt;archivage.conf&lt;/code&gt; pour porter nos configurations. Une fois le fichier crée ajoute ce contenu :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;listen_addresses &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'*'&lt;/span&gt;
wal_level &lt;span class="o"&gt;=&lt;/span&gt; replica
archive_mode &lt;span class="o"&gt;=&lt;/span&gt; on
archive_command &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'rsync -a %p barman@192.168.58.12:/var/lib/barman/pg/incoming/%f'&lt;/span&gt;
max_wal_senders &lt;span class="o"&gt;=&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explications&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;wal_level = replica&lt;/code&gt; : definit le niveau de journalisation minimal pour permettre les sauvegardes incrémentales.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;archive_mode = on&lt;/code&gt; : active l’archivage des WAL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;archive_command&lt;/code&gt; : commande à exécuter à chaque rotation de logs expliqué dans la première partie de la série; ici on indique à PostgreSQL comment transférer chaque fichier WAL vers le serveur Barman en utilisant &lt;code&gt;rsync&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;max_wal_senders&lt;/code&gt; : nombre maximum de connexions pour envoyer des WAL à des clients (comme Barman).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ &lt;strong&gt;Astuce&lt;/strong&gt; : Vérifie que la commande &lt;code&gt;rsync&lt;/code&gt; fonctionne en testant manuellement la copie d’un fichier entre les serveurs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  🔐 Autoriser les connexions Barman dans pg_hba.conf
&lt;/h3&gt;

&lt;p&gt;Dans le fichier &lt;code&gt;/etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf&lt;/code&gt;, ajoute cette ligne pour autoriser l’utilisateur Barman à se connecter :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Connexion pour les sauvegardes&lt;/span&gt;
host    replication     barman     192.168.58.12/32      md5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensuite assure-toi que l’utilisateur &lt;code&gt;barman&lt;/code&gt; existe dans PostgreSQL, avec un mot de passe sécurisé :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;createuser &lt;span class="nt"&gt;--superuser&lt;/span&gt; &lt;span class="nt"&gt;--replication&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; barman
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🚀 Redémarrer PostgreSQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Une fois ces modifications faites, &lt;strong&gt;redémarre PostgreSQL&lt;/strong&gt; pour qu’elles prennent effet :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ Configuration de Barman pour les sauvegardes incrémentales
&lt;/h2&gt;

&lt;p&gt;Une fois PostgreSQL prêt à envoyer ses WAL, il est temps de préparer &lt;strong&gt;Barman&lt;/strong&gt; pour recevoir, stocker et gérer les sauvegardes; notamment les incrémentales.&lt;/p&gt;

&lt;h3&gt;
  
  
  📁 Configuration du répertoire de sauvegarde
&lt;/h3&gt;

&lt;p&gt;Par défaut, Barman stocke ses données dans le répertoire &lt;code&gt;/var/lib/barman&lt;/code&gt;. Il faut créer un sous-répertoire pour chaque serveur PostgreSQL à sauvegarder.&lt;br&gt;&lt;br&gt;
Puisqu’on a deja installé barman sur le serveur exécute donc :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/lib/barman/pg
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; barman:barman /var/lib/barman/pg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tu peux aussi personnaliser l’emplacement via le fichier de configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧾 Fichier de configuration &lt;code&gt;barman.conf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Le fichier global est&lt;code&gt;/etc/barman.conf&lt;/code&gt; et chaque serveur pourra avoir sa propre configuration dans &lt;code&gt;/etc/barman.d/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Voici un exemple de configuration minimale pour notre serveur nommé pg :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# fichier pg.conf&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;pg]
description &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Serveur PostgreSQL principal"&lt;/span&gt;
conninfo &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;192.168.58.11 &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;barman &lt;span class="nv"&gt;dbname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;test_db
ssh_command &lt;span class="o"&gt;=&lt;/span&gt; ssh postgres@192.168.58.11
backup_method &lt;span class="o"&gt;=&lt;/span&gt; rsync
streaming_archiver &lt;span class="o"&gt;=&lt;/span&gt; on
slot_name &lt;span class="o"&gt;=&lt;/span&gt; barman
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 &lt;strong&gt;Explications des options importantes&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;conninfo&lt;/code&gt; : comment se connecter à PostgreSQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ssh_command&lt;/code&gt; : connexion SSH utilisée par &lt;code&gt;rsync&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;backup_method&lt;/code&gt; : &lt;code&gt;rsync&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;streaming_archiver = on&lt;/code&gt; : permet de récupérer les WAL en continu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;slot_name&lt;/code&gt; : nom du slot de réplication utilisé par Barman pour les WAL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚙️ Paramètres avancés utiles
&lt;/h3&gt;

&lt;p&gt;Tu peux adapter la configuration à ton usage :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;reuse_backup &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;link
&lt;/span&gt;retention_policy &lt;span class="o"&gt;=&lt;/span&gt; RECOVERY WINDOW OF 7 DAYS
compression &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;gzip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;reuse_backup = link&lt;/code&gt; : évite les duplications de fichiers lors des backups incrémentaux.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;retention_policy&lt;/code&gt; : conserve les sauvegardes nécessaires pour restaurer jusqu’à 7 jours en arrière.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;compression&lt;/code&gt; : compresse les sauvegardes pour gagner de l’espace disque.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Toutes les options de configuration sont détaillées sur la &lt;a href="https://pgbarman.org/documentation/" rel="noopener noreferrer"&gt;documentation officielle de Barmn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Afin que barman puisse se connecter via l'utilisateur spécifié à la base de données, nous devons ajouter le mot de passe que nous avons spécifié à la création de l’utilisateur barman au fichier .&lt;a href="https://www.postgresql.org/docs/current/libpq-pgpass.html" rel="noopener noreferrer"&gt;pgpass&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su barman
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt;&amp;gt;~/.pgpass
mon_serveur:5432:test_db:barman:password
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;0600 ~/.pgpass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chaque ligne de ce fichier doit etre au format&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[db_hote]:[db_port]:[db_nom]:[db_user]:[db_password]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Vérifier que tout fonctionne
&lt;/h3&gt;

&lt;p&gt;Avant de lancer un backup, vérifie la connexion entre Barman et PostgreSQL; à cette étape tous les voyants doivent etre au vert 🕺💃 et tu dois avoir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman check pg
Server pg:
    PostgreSQL: OK
    is_superuser: OK
    wal_level: OK
    directories: OK
    retention policy settings: OK
    backup maximum age: OK &lt;span class="o"&gt;(&lt;/span&gt;no last_backup_maximum_age provided&lt;span class="o"&gt;)&lt;/span&gt;
    compression settings: OK
    failed backups: OK &lt;span class="o"&gt;(&lt;/span&gt;there are 0 failed backups&lt;span class="o"&gt;)&lt;/span&gt;
    minimum redundancy requirements: OK &lt;span class="o"&gt;(&lt;/span&gt;have 0 backups, expected at least 0&lt;span class="o"&gt;)&lt;/span&gt;
    ssh: OK &lt;span class="o"&gt;(&lt;/span&gt;PostgreSQL server&lt;span class="o"&gt;)&lt;/span&gt;
    systemid coherence: OK
    archive_mode: OK
    archive_command: OK
    continuous archiving: OK
    archiver errors: OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tu peux aussi à présent lancer ton premier test de sauvegarde, si tout se passe bien tu dois avoir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman backup pg
Starting the backup using the rsync-concurrent method &lt;span class="k"&gt;for &lt;/span&gt;the pg server &lt;span class="k"&gt;in&lt;/span&gt; /var/lib/barman/pg/base/20250413T113210
Backup start at LSN: 0/12000060 &lt;span class="o"&gt;(&lt;/span&gt;000000010000000000000012, 00000060&lt;span class="o"&gt;)&lt;/span&gt;
This is the first backup &lt;span class="k"&gt;for &lt;/span&gt;the pg server
The WAL segments preceding the current backup were found:
        000000010000000000000000F from pg server has been removed
        0000000100000000000000010 from server pg has been removed
Starting backup via rsync/SSH &lt;span class="k"&gt;for &lt;/span&gt;20250413T113210
Completed copy &lt;span class="o"&gt;(&lt;/span&gt;duration: 3 seconds&lt;span class="o"&gt;)&lt;/span&gt;
This is the first backup &lt;span class="k"&gt;for &lt;/span&gt;the server pg
Asking the PostgreSQL server to finalize the backup.
Backup size: 38.8 MiB. Actual disk size: 38.8 MiB &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-0&lt;/span&gt;.00% deduplication ratio&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Backup end at LSN: 0/12000138 &lt;span class="o"&gt;(&lt;/span&gt;00000001000000000000012, 00000138&lt;span class="o"&gt;)&lt;/span&gt;
Backup completed &lt;span class="o"&gt;(&lt;/span&gt;start &lt;span class="nb"&gt;time&lt;/span&gt;: 2025-04-13 11:32:10.136973, &lt;span class="nb"&gt;time &lt;/span&gt;elapsed: 5 seconds&lt;span class="o"&gt;)&lt;/span&gt;
Processing xlog segments from file archiving &lt;span class="k"&gt;for &lt;/span&gt;pg
        000000010000000000000011
        000000010000000000000012
        000000010000000000000012.00000060.backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔁 Automatiser les sauvegardes incrémentales avec Barman
&lt;/h3&gt;

&lt;p&gt;Une fois Barman et PostgreSQL correctement configurés, il est essentiel d’automatiser les sauvegardes pour garantir la protection continue de vos données. Heureusement, Barman s’intègre facilement avec les outils classiques de planification de tâches, comme &lt;strong&gt;cron&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  🕒 Planifier les sauvegardes avec &lt;code&gt;cron&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Pour déclencher automatiquement une sauvegarde, il suffit d’ajouter une tâche cron sur le serveur Barman. Par exemple, pour lancer une sauvegarde complète tous les jours à 2h du matin :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Se connecter en tant que&lt;/strong&gt; &lt;code&gt;barman&lt;/code&gt; :
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; barman crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ajouter la tâche cron dans cette crontab&lt;/strong&gt; :
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;0 2 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; barman backup pg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 &lt;em&gt;Pensez à tester votre commande manuellement avant de l’automatiser, pour vérifier que tout fonctionne comme prévu.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  📉 Astuces pour optimiser l’espace disque
&lt;/h4&gt;

&lt;p&gt;Voici quelques conseils pour conserver vos sauvegardes tout en maîtrisant l’utilisation du stockage :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🗃️ &lt;strong&gt;Compression des sauvegardes&lt;/strong&gt; : Barman propose la compression automatique des fichiers; possible avec &lt;code&gt;compression = gzip&lt;/code&gt; utilisée plus haut dans nos configurations:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🧹 &lt;strong&gt;Suppression automatique des anciennes sauvegardes&lt;/strong&gt; : utilisez la politique de rétention pour ne conserver que les sauvegardes nécessaires; possible avec &lt;code&gt;retention_policy = RECOVERY WINDOW OF 7 DAYS&lt;/code&gt; aussi utilisé dans notre fichier &lt;code&gt;pg.conf&lt;/code&gt; .&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔍 Surveillance et gestion des sauvegardes avec Barman
&lt;/h2&gt;

&lt;p&gt;Une fois les sauvegardes en place, il est crucial de &lt;strong&gt;les surveiller&lt;/strong&gt; et de &lt;strong&gt;gérer leur cycle de vie&lt;/strong&gt; pour garantir leur efficacité. Barman fournit plusieurs outils pour cela, directement utilisables en ligne de commande.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Vérifier l’état des sauvegardes
&lt;/h3&gt;

&lt;p&gt;Barman dispose de plusieurs commandes utiles pour &lt;strong&gt;suivre l'état de vos sauvegardes et de vos serveurs&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  🔧 Lister les sauvegardes disponibles
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman list-backup pg
pg 20250415T201754 - Tue Apr 15 20:17:58 2025 - Size: 54.9 MiB - WAL Size: 16.0 MiB
pg 20250415T201516 - Tue Apr 15 20:15:19 2025 - Size: 54.9 MiB - WAL Size: 48.0 MiB
pg 20250413T113210 - Sun Apr 13 11:32:14 2025 - Size: 54.8 MiB - WAL Size: 32.0 MiB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette commande affiche entre autre :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;l’&lt;strong&gt;ID&lt;/strong&gt; de chaque sauvegarde,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;la &lt;strong&gt;date&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;le &lt;strong&gt;point de récupération possible&lt;/strong&gt; (PITR)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📊 Vérifier l’état général du serveur
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman check nom_du_serveur
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette commande fait un &lt;strong&gt;diagnostic complet&lt;/strong&gt; de la configuration : connexions SSH, configuration PostgreSQL, accès aux répertoires de sauvegarde, etc.&lt;/p&gt;

&lt;h4&gt;
  
  
  Obtenir des détails sur une sauvegarde spécifique
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;barman show-backup nom_du_serveur ID_sauvegarde
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utile pour voir entre autre:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;les chemins utilisés,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;la taille de la sauvegarde,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;les fichiers WAL associés,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;les options activées.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧯 Et en cas de problème ?
&lt;/h3&gt;

&lt;p&gt;En cas d’échec de sauvegarde :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Lance &lt;code&gt;barman check&lt;/code&gt; pour diagnostiquer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consulte les logs postgres et barman dans respectivement &lt;code&gt;/var/log/postgresql&lt;/code&gt; et &lt;code&gt;/var/log/barman/&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏁 Conclusion : Garder le contrôle sur vos sauvegardes PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Dans cette seconde partie, nous avons plongé dans les &lt;strong&gt;aspects techniques essentiels&lt;/strong&gt; pour éléborer une stratégie de sauvegarde incrémentale fiable avec Barman. De la configuration fine de PostgreSQL, à la mise en place des connexions sécurisées en passant par l’automatisation via cron et la surveillance proactive, chaque étape renforce la &lt;strong&gt;robustesse&lt;/strong&gt; et la &lt;strong&gt;résilience&lt;/strong&gt; de votre base de données.&lt;/p&gt;

&lt;p&gt;Grâce à Barman, vous disposez d’un outil &lt;strong&gt;puissant&lt;/strong&gt;, &lt;strong&gt;souple&lt;/strong&gt; et &lt;strong&gt;open source&lt;/strong&gt;, capable de répondre aux besoins des environnements de production les plus exigeants. Mais la maîtrise des sauvegardes ne s’arrête pas là.&lt;/p&gt;

&lt;p&gt;Dans la &lt;a href="https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-restauration-partie-3-33n3"&gt;prochaine partie&lt;/a&gt;, nous verrons comment &lt;strong&gt;restaurer efficacement une base de données PostgreSQL&lt;/strong&gt;, notamment via le &lt;strong&gt;Point In Time Recovery (PITR)&lt;/strong&gt;, ainsi que des &lt;strong&gt;cas pratiques&lt;/strong&gt; pour tester vos sauvegardes.&lt;/p&gt;

&lt;p&gt;👉 Restez connectés pour aller jusqu’au bout de votre stratégie de sauvegarde PostgreSQL !&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>backup</category>
      <category>database</category>
    </item>
    <item>
      <title>Configurer des sauvegardes incrémentales avec PostgreSql - Introduction-Partie 1</title>
      <dc:creator>ZINSOU Trinité</dc:creator>
      <pubDate>Mon, 02 Jun 2025 23:46:35 +0000</pubDate>
      <link>https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-introduction-partie-1--12i0</link>
      <guid>https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-introduction-partie-1--12i0</guid>
      <description>&lt;h2&gt;
  
  
  🧭 Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt; est un système de gestion de bases de données robuste, fiable, et très utilisé dans le monde du développement. Il respecte les standards SQL, il est open source, et surtout, il garde précieusement nos données.&lt;/p&gt;

&lt;p&gt;Mais même le meilleur outil ne peut rien contre une mauvaise manip, un bug, ou un crash serveur. C’est là qu’intervient notre meilleure alliée : &lt;strong&gt;la sauvegarde&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Dans ce guide, on va découvrir &lt;strong&gt;comment configurer des sauvegardes incrémentales sur PostgreSQL&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
L’objectif ? Que tu sois développeur, administrateur, étudiant ou simplement curieux, tu pourras &lt;strong&gt;mettre en place un système de sauvegarde automatique, efficace et rassurant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On va :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;comprendre ce qu’est une sauvegarde (et une sauvegarde incrémentale 🧠),&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;découvrir les outils disponibles dans PostgreSQL 🔧,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;configurer étape par étape notre système de sauvegarde incrémentale 🛠️,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;automatiser le tout avec des scripts et &lt;code&gt;cron&lt;/code&gt; ⏰,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;et même tester la restauration (parce qu’une sauvegarde non testée, c’est juste une illusion de sécurité 😉).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Prêt ? Alors on commence par les bases. 👇&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 Rappel : qu’est-ce qu’une sauvegarde (et une sauvegarde incrémentale) ?
&lt;/h2&gt;

&lt;p&gt;Avant de plonger dans la configuration, prenons une minute pour poser les bases, parce qu’une bonne compréhension, c’est déjà la moitié du boulot.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔐 Une sauvegarde, c’est quoi ?
&lt;/h3&gt;

&lt;p&gt;C’est tout simplement une &lt;strong&gt;copie de données&lt;/strong&gt; (fichiers, bases, configurations, etc.) qu’on garde &lt;strong&gt;à part&lt;/strong&gt;, dans un coin sûr, pour pouvoir &lt;strong&gt;les récupérer en cas de pépin&lt;/strong&gt; : erreur humaine, panne, piratage, ou juste un “Oups, j’ai tout supprimé”.&lt;/p&gt;
&lt;h3&gt;
  
  
  🧱 Les 3 grands types de sauvegardes
&lt;/h3&gt;

&lt;p&gt;Il existe plusieurs façons de sauvegarder ses données. Voici les trois principales :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sauvegarde complète&lt;/strong&gt; : on copie &lt;strong&gt;tous les fichiers&lt;/strong&gt; à chaque fois. C’est simple, mais ça peut vite devenir lourd en espace disque.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sauvegarde différentielle&lt;/strong&gt; : on copie uniquement les fichiers qui ont changé &lt;strong&gt;depuis la dernière sauvegarde complète&lt;/strong&gt;. C’est plus léger, mais au fil du temps, ça peut s’accumuler.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sauvegarde incrémentale&lt;/strong&gt; : on copie les fichiers qui ont changé &lt;strong&gt;depuis la dernière sauvegarde, quelle qu’elle soit&lt;/strong&gt; (complète ou incrémentale). C’est la plus optimisée en taille et en temps, mais un peu plus technique à gérer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  📌 Pourquoi les sauvegardes incrémentales sont cool ?
&lt;/h3&gt;

&lt;p&gt;Parce qu’elles permettent de &lt;strong&gt;gagner du temps et de l’espace&lt;/strong&gt;, tout en conservant l’historique des modifications. Et la bonne nouvelle, c’est que PostgreSQL permet ce type de sauvegarde en s’appuyant sur un mécanisme intégré de &lt;strong&gt;journalisation anticipée&lt;/strong&gt; (&lt;a href="https://docs.postgresql.fr/14/wal-intro.html" rel="noopener noreferrer"&gt;&lt;strong&gt;WAL&lt;/strong&gt;&lt;/a&gt; : &lt;em&gt;Write-Ahead Logging&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;👉 C’est justement ce qu’on va exploiter dans ce guide.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔍 Comment Postgres permet-il les sauvegardes incrémentales ?
&lt;/h2&gt;

&lt;p&gt;Nous allons nous intéresser dans un premier temps aux possibilités de sauvegarde offertes par PostgreSQL, afin de comprendre les différents mécanismes disponibles avant de se plonger dans la configuration des sauvegardes incrémentales.&lt;/p&gt;
&lt;h3&gt;
  
  
  🧬 Les différents types de sauvegarde avec PostgreSQL
&lt;/h3&gt;

&lt;p&gt;Postgresql offre trois possibilités 👇:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Sauvegarde complète&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Elle consiste à copier l’intégralité de la base de données à un instant donné. Ce type de sauvegarde est un &lt;strong&gt;&lt;em&gt;instantané&lt;/em&gt;&lt;/strong&gt; de la base et permet de restaurer une base de données dans son état précis au moment de la sauvegarde. Cela peut être effectué avec des outils comme &lt;a href="https://www.postgresql.org/docs/14/app-pgbasebackup.html" rel="noopener noreferrer"&gt;&lt;code&gt;pg_basebackup&lt;/code&gt;&lt;/a&gt;, ou manuellement en copiant les fichiers de données de PostgreSQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Sauvegarde logique (pg_dump)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Elle utilise l’outil &lt;a href="https://www.postgresql.org/docs/14/app-pgdump.html" rel="noopener noreferrer"&gt;&lt;code&gt;pg_dump&lt;/code&gt;&lt;/a&gt;, qui exporte les données de la base sous forme de script SQL. Il s’agit d’une forme de sauvegarde complète qui permet de récupérer la base de données sous un format indépendant de PostgreSQL. Cette méthode est souvent utilisée pour migrer des bases de données ou pour effectuer des sauvegardes spécifiques (par exemple, d’une table ou d’un schéma). Toutefois, elle a des limites pour les sauvegardes incrémentales, car elle n’inclut pas directement les journaux de transactions (WAL).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Sauvegarde incrémentale (basée sur les WAL)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La &lt;strong&gt;sauvegarde incrémentale&lt;/strong&gt;, comme son nom l’indique, permet de ne sauvegarder que les modifications effectuées après une première sauvegarde complète. Cela repose sur l’archivage des fichiers WAL (Write-Ahead Log) générés par PostgreSQL. Ces fichiers contiennent un enregistrement de toutes les transactions qui ont été appliquées à la base de données. En utilisant les fichiers WAL, il est possible de restaurer la base de données à un moment précis, ce qui permet d’atteindre un &lt;strong&gt;objectif&lt;/strong&gt; &lt;a href="https://www.acronis.com/en-us/blog/posts/rto-rpo/" rel="noopener noreferrer"&gt;&lt;strong&gt;RPO&lt;/strong&gt;&lt;/a&gt; (Recovery Point Objective) très bas, souvent à quelques minutes seulement. Il s’agit ici de minimiser la quantité de donnée qu’on est prêt à perdre après un incident.&lt;/p&gt;
&lt;h3&gt;
  
  
  🧪 Les sauvegardes incrémentales
&lt;/h3&gt;

&lt;p&gt;PostgreSQL offre une fonctionnalité clé qui permet de réaliser des sauvegardes incrémentales : le &lt;strong&gt;Write-Ahead Logging (WAL)&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Chaque opération d’écriture sur la base de données est journalisée dans des fichiers de log. Ces fichiers enregistrent les modifications de la base de données avant que celles-ci ne soient réellement appliquées, garantissant ainsi l'intégrité des données.&lt;br&gt;&lt;br&gt;
Ce mécanisme, appelé &lt;strong&gt;WAL&lt;/strong&gt;, permet de &lt;strong&gt;restaurer l'état de la base de données à un moment précis&lt;/strong&gt;, une technique connue sous le nom de &lt;a href="https://en.wikipedia.org/wiki/Point-in-time_recovery" rel="noopener noreferrer"&gt;&lt;strong&gt;Point In Time Recovery (PITR)&lt;/strong&gt;&lt;/a&gt;. Cela signifie qu'après une première sauvegarde complète, vous pouvez restaurer une base de données à n'importe quel instant en récupérant les fichiers WAL générés depuis cette sauvegarde.&lt;br&gt;&lt;br&gt;
C'est exactement ce que nous allons exploiter dans notre configuration avec &lt;strong&gt;Barman&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚙️ Principe de fonctionnement du WAL
&lt;/h3&gt;

&lt;p&gt;Lorsque l'archivage des WAL est activé dans PostgreSQL, il génère des fichiers dans un dossier spécifique (&lt;code&gt;/var/lib/postgresql/{version}/main/pg_wal/&lt;/code&gt;) à chaque opération d'écriture. Ces fichiers font l’objet d’une rotation dès qu’ils atteignent une taille de &lt;strong&gt;16 Mo&lt;/strong&gt; par défaut.&lt;br&gt;&lt;br&gt;
Chaque fois qu'un fichier WAL est modifié ou créé, PostgreSQL permet de définir une &lt;strong&gt;commande&lt;/strong&gt; spécifique à exécuter. Cela permet de &lt;strong&gt;centrer l'archivage&lt;/strong&gt; des fichiers WAL et de gérer plus facilement la récupération des données.&lt;/p&gt;

&lt;p&gt;Barman va s’appuyer sur ces fichiers WAL pour faciliter la gestion des sauvegardes incrémentales et des restaurations à un moment précis.&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀C'est quoi Barman ?
&lt;/h2&gt;
&lt;h3&gt;
  
  
  🍹Découverte de barman
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Barman&lt;/strong&gt; (Backup and Recovery Manager) est un outil écrit en &lt;strong&gt;Python&lt;/strong&gt; qui facilite la gestion des sauvegardes et restaurations des bases de données PostgreSQL.&lt;br&gt;&lt;br&gt;
Ce gestionnaire de sauvegardes est spécialement conçu pour PostgreSQL et simplifie :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;La planification et l’automatisation des sauvegardes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;La gestion des sauvegardes complètes et incrémentales.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;La récupération &lt;strong&gt;Point-in-Time Recovery (PITR)&lt;/strong&gt; en utilisant les fichiers WAL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il est particulièrement pratique pour gérer plusieurs serveurs PostgreSQL en centralisant les opérations de sauvegarde et de restauration en un seul endroit.&lt;br&gt;&lt;br&gt;
Ce sera l'outil que nous allons configurer et utiliser dans cet article.&lt;/p&gt;
&lt;h3&gt;
  
  
  🤔 Barman vs pg_dump
&lt;/h3&gt;

&lt;p&gt;Avant d’aller plus loin, faisons une petite comparaison entre &lt;strong&gt;Barman&lt;/strong&gt; et les outils classiques de sauvegarde PostgreSQL : &lt;strong&gt;pg_dump/pg_basebackup&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;pg_dump / pg_basebackup&lt;/strong&gt; : Ces outils permettent des sauvegardes complètes, où vous pouvez exporter l'état d'une base de données (sous forme de script SQL par exemple, avec des options pour une table, un schéma, ou toute la base). Cependant, &lt;strong&gt;pg_dump/pg_basebackup&lt;/strong&gt; ne conviennent pas pour des restaurations rapides en cas de sinistre, car vous devez toujours restaurer à partir de &lt;strong&gt;l’heure précise de la sauvegarde&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Essayons nous à une petite expérience de pensée; vous faites régulièrement vos sauvegardes avec pg_dump par exemple à 3 heures du matin et vous avez un crash/incident à 18 heures. Vu que pg_dump récupère l'état de votre système à une heure bien précise (ici 3h), et qu’un incident survient à 18h, vous perdrez toutes les données ajoutées depuis la dernière sauvegarde. On parle bien de 15h de données, dans tous les scénarios, cette perte est &lt;strong&gt;inacceptable&lt;/strong&gt; pour de nombreuses entreprises.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Barman&lt;/strong&gt; : Contrairement à &lt;code&gt;pg_dump&lt;/code&gt;, &lt;strong&gt;Barman opère au niveau physique&lt;/strong&gt; de la base de données. Cela signifie qu'il prend des &lt;strong&gt;copies complètes&lt;/strong&gt; et &lt;strong&gt;incrémentales&lt;/strong&gt; de vos données, permettant de récupérer tout ce qui a changé depuis la dernière sauvegarde, sans risquer une perte importante de données. Ce système est particulièrement adapté pour des &lt;strong&gt;objectifs RPO&lt;/strong&gt; (Recovery Point Objective) bas, réduisant ainsi la perte de données à quelques minutes seulement.&lt;br&gt;&lt;br&gt;
Bien sûr, cela nécessite un peu plus d’espace disque pour stocker les sauvegardes, mais le compromis en termes de sécurité et de récupération est largement justifié.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  📦 Installation de barman
&lt;/h3&gt;

&lt;p&gt;Avant de pouvoir utiliser &lt;strong&gt;Barman&lt;/strong&gt; pour la gestion des sauvegardes incrémentales, il est nécessaire de s'assurer que les composants Postgresql sont bien installés. Pour les utilisateurs d’&lt;code&gt;Ubuntu&lt;/code&gt; &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-22-04" rel="noopener noreferrer"&gt;ce tutoriel&lt;/a&gt; est excellent pour l’installation de PostgreSQL. Pour ceux avec &lt;code&gt;CentOs/RHEL&lt;/code&gt; vous pouvez suivre &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-centos-8" rel="noopener noreferrer"&gt;celui-ci&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Une fois PostgreSQL installé et pret à l’utilisation, nous reviendrons sur les configuration plus avancées nécessaire à notre sauvegarde. A présent passons maintenant à l’installation de Barman&lt;/p&gt;
&lt;h4&gt;
  
  
  a. &lt;strong&gt;Sur Ubuntu/Debian&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Sur les distributions basées sur Debian comme &lt;strong&gt;Ubuntu&lt;/strong&gt;, vous pouvez installer Barman directement depuis les dépôts officiels.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Installation depuis les depôts&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;barman
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Vérifier l'installation&lt;/strong&gt; :&lt;/p&gt;

&lt;p&gt;Une fois l'installation terminée, vérifiez que Barman est bien installé en exécutant la commande suivante :&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;/ol&gt;

&lt;h4&gt;
  
  
  b. &lt;strong&gt;Sur CentOS/RHEL&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Sur &lt;strong&gt;CentOS&lt;/strong&gt; ou &lt;strong&gt;RHEL&lt;/strong&gt;, vous devez d’abord ajouter le dépôt officiel de Barman avant de l’installer.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ajouter le dépôt officiel Barman&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; https://dl.enterprisedb.com/barman/barman-2.16.0-1.rhel7.x86_64.rpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mettre à jour les paquets système&lt;/strong&gt; &lt;strong&gt;et installer barman&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum update
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;barman
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Vérifier l'installation&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;barman &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🧾 Conclusion
&lt;/h2&gt;

&lt;p&gt;Dans cet article, nous avons exploré les concepts fondamentaux nécessaires à la mise en place de sauvegardes incrémentales sur PostgreSQL, en mettant l'accent sur le rôle essentiel des journaux de transactions (WAL) et le mécanisme de &lt;strong&gt;PITR&lt;/strong&gt;. Nous avons également vu comment &lt;strong&gt;Barman&lt;/strong&gt;, l'outil de gestion de sauvegarde et de restauration, s'intègre parfaitement dans ce processus.&lt;/p&gt;

&lt;p&gt;L’objectif était de fournir une compréhension claire de ce qu'implique une sauvegarde incrémentale avec PostgreSQL avant de plonger dans la configuration technique elle-même. Ces bases vous permettent d’avoir une vue d’ensemble sur les enjeux et les outils à utiliser pour une gestion efficace des sauvegardes.&lt;/p&gt;

&lt;p&gt;Dans la &lt;a href="https://dev.to/trinitezinsou/configurer-des-sauvegardes-incrementales-avec-postgresql-mise-en-place-partie-2-f6o"&gt;partie 2&lt;/a&gt;, nous entrerons dans le vif du sujet avec la configuration complète de Barman : : de l’installation à l’activation des sauvegardes incrémentales. Nous aborderons également les bonnes pratiques pour garantir la continuité et la fiabilité de vos sauvegardes.&lt;/p&gt;

&lt;p&gt;Rendez-vous dans le prochain article pour découvrir comment configurer et automatiser vos sauvegardes de manière optimale.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>backup</category>
      <category>database</category>
    </item>
  </channel>
</rss>
