SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor

Sauvegarder et mettre à niveau une stack Docker Compose

Découvrez quoi sauvegarder dans Docker Compose, quels volumes capturer, comment vérifier une restauration et pourquoi sauvegarder avant le pull et les migrations.

Ce que doit contenir la sauvegarde d’une stack Docker Compose

La sauvegarde d’une stack Docker Compose doit contenir quatre éléments distincts. Si l’un d’eux manque, l’application ne redémarrera pas : le fichier Compose, le fichier .env placé à côté, le contenu de chaque volume et un dump de la base de données créé avec le client propre à cette base. Copier les fichiers d’une base de données pendant que son conteneur s’exécute ne constitue pas une sauvegarde. Les mises à niveau suivent la même liste, avec une règle supplémentaire : effectuez la sauvegarde avant le pull, car les migrations de schéma sont conçues pour avancer et la plupart des projets ne proposent aucun retour arrière.

Tout ce qui suit suppose que la stack est déjà déployée et que docker compose ps indique qu’elle fonctionne. Les exemples utilisent un répertoire de projet situé dans /srv/myapp, avec des services nommés app et db. Remplacez-les par vos propres noms. Les commandes restent volontairement génériques, car les éléments importants, les volumes et la base de données, se gèrent de la même manière quelle que soit l’application.

Déterminez ce que votre stack stocke réellement

cd /srv/myapp
docker compose ps
docker compose config --volumes
docker volume ls --filter label=com.docker.compose.project=myapp

docker compose config --volumes affiche les noms courts des volumes nommés déclarés dans votre fichier. docker volume ls affiche les noms réellement utilisés par ces volumes sur le disque. Les deux listes diffèrent, car Compose préfixe le nom du projet : un volume écrit sous la forme db_data dans le fichier existe sous le nom myapp_db_data. Par défaut, le nom du projet correspond au nom du répertoire. Renommer ce répertoire fait donc pointer la stack vers un nouvel ensemble de volumes vides et laisse les anciens sur le serveur avec toutes vos données. Toutes les commandes ci-dessous nécessitent le nom réel obtenu avec docker volume ls.

Les bind mounts n’apparaissent dans aucune des deux listes. Dans le fichier Compose, ce sont les entrées qui indiquent un chemin de l’hôte à gauche des deux-points, ./config:/app/config. Ce sont de simples répertoires sur l’hôte, accessibles avec les outils habituels. Les volumes nommés se trouvent sous /var/lib/docker/volumes/, et docker volume inspect --format '{{.Mountpoint}}' myapp_db_data affiche le chemin exact de l’un d’eux. Le type de stockage utilisé par votre stack détermine la méthode de copie ; bind mounts et volumes nommés présente ce compromis en détail.

Classez ensuite les éléments trouvés en deux groupes. Certains volumes contiennent un état impossible à recréer : fichiers téléversés, clés générées, base de données et toute donnée saisie par un utilisateur dans l’application. D’autres contiennent des données dérivées, comme les miniatures et les index de recherche, que l’application reconstruit elle-même. Sauvegarder le second groupe consomme de l’espace disque et augmente la durée de restauration, sans apporter de bénéfice. Un volume de cache Redis en est l’exemple le plus clair : sa perte entraîne seulement une première requête plus lente.

Sauvegarder le fichier Compose et le fichier .env

Les deux fichiers se trouvent côte à côte sur l’hôte, et aucun des deux n’est stocké dans un volume. Le .env contient le mot de passe de la base de données, le secret de l’application et les éventuels jetons d’API. C’est donc lui qui permet de transformer un ensemble de volumes en application fonctionnelle. Il est aussi généralement répertorié dans .gitignore. Un plan selon lequel « ma configuration est dans git » exclut donc le fichier le plus important. Conserver les secrets dans un fichier env est la bonne méthode. Elle impose également de sauvegarder ce fichier.

sudo install -d -m 700 -o "$USER" -g "$(id -gn)" /srv/backups/myapp
cp -a compose.yaml .env /srv/backups/myapp/
chmod 600 /srv/backups/myapp/.env

Copiez tous les fichiers Compose utilisés par la stack, et pas uniquement le premier. Une stack démarrée avec -f compose.yaml -f compose.prod.yaml nécessite la restauration des deux fichiers à l’identique. La fusion de plusieurs fichiers Compose détermine les valeurs effectivement transmises au conteneur.

Un point important relie le .env aux volumes. L’image officielle Postgres ne lit POSTGRES_PASSWORD que lorsqu’elle initialise un répertoire de données vide. Modifier cette valeur par la suite ne change pas le mot de passe dans la base de données. Si vous restaurez le volume du mois dernier avec le .env du jour, l’application ne parvient pas à se connecter avec FATAL: password authentication failed for user "appuser", alors que les deux fichiers semblent corrects à l’inspection. Conservez le .env et les volumes provenant du même moment dans la même sauvegarde.

Exporter la base de données avec son propre client

Un serveur de base de données écrit constamment dans ses fichiers. Un tar de /var/lib/postgresql/data effectué pendant que le serveur fonctionne copie certaines pages avant une écriture et d’autres après. L’archive contient donc un mélange d’états qui ne pourront peut-être pas être rejoués. Un outil de dump lit les données dans le cadre d’une transaction unique. Le fichier représente donc un état cohérent. Cette différence sépare une sauvegarde d’une simple copie.

docker compose exec -T db sh -c \
  'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' \
  > /srv/backups/myapp/db-$(date +%F).dump

Conservez le -T. Il désactive l’allocation d’un TTY. Avec un TTY attaché, Docker transforme le flux de sortie avant de le transmettre à votre shell, ce qui corrompt un dump binaire. Vous ne le découvrirez qu’au moment où la restauration échouera. Les apostrophes simples sont également importantes : elles empêchent votre shell hôte de développer $POSTGRES_USER. Le shell exécuté dans le conteneur le développe à sa place, avec les valeurs déjà définies par le fichier compose. -Fc écrit au format custom. Ce format compresse les données pendant l’écriture et permet ensuite à pg_restore d’en extraire certains objets.

Les rôles et leurs mots de passe sont stockés en dehors de chaque base de données. Exportez-les également :

docker compose exec -T db sh -c 'pg_dumpall -U "$POSTGRES_USER" --globals-only' \
  > /srv/backups/myapp/globals.sql

Vérifiez ensuite que le fichier est bien un dump et non un message d’erreur :

ls -lh /srv/backups/myapp/
head -c 5 /srv/backups/myapp/db-$(date +%F).dump

Un dump au format custom commence par les cinq octets PGDMP. Un fichier de taille nulle ou un fichier qui commence par pg_dump: indique que la commande a échoué. Le shell crée le fichier de sortie avant d’exécuter la commande. Un dump échoué laisse donc malgré tout un fichier avec un nom et une date plausibles. C’est la cause la plus fréquente d’échec silencieux d’une sauvegarde.

Pour MariaDB ou MySQL, le client change, mais la méthode reste la même :

docker compose exec -T db sh -c \
  'mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" --single-transaction --databases "$MARIADB_DATABASE"' \
  > /srv/backups/myapp/db-$(date +%F).sql

--single-transaction produit un dump cohérent des tables InnoDB sans bloquer les écritures. Avec l’image MySQL, la commande est mysqldump et les variables sont MYSQL_ROOT_PASSWORD et MYSQL_DATABASE. Dans les images MariaDB actuelles, mysqldump reste un nom de compatibilité pour mariadb-dump. Notez qu’un mot de passe fourni sur la ligne de commande reste visible dans la liste des processus du conteneur pendant toute la durée du dump.

SQLite nécessite des précautions particulières. La base de données tient dans un seul fichier, mais des transactions récentes peuvent encore se trouver dans un fichier -wal séparé, placé à côté. Copier uniquement le .db produit donc une base de données à laquelle il manque ses écritures les plus récentes. Si l’image fournit le client, sqlite3 /data/app.db ".backup '/data/app-backup.db'" écrit une copie cohérente pendant que l’application fonctionne. Sinon, arrêtez le conteneur et copiez le fichier .db avec ses fichiers associés -wal et -shm.

Si votre base de données s’exécute sur l’hôte plutôt que dans la stack, les mêmes commandes s’appliquent sans le préfixe docker compose exec. Consultez aussi exécuter la base de données dans Docker ou sur l’hôte avant votre prochaine reconstruction.

Capturer les volumes

Un volume nommé n’a pas de chemin d’hôte à modifier manuellement. Montez-le donc dans un conteneur temporaire, puis créez l’archive depuis ce conteneur.

docker run --rm \
  -v myapp_uploads:/data:ro \
  -v /srv/backups/myapp:/backup \
  alpine:3 tar czf /backup/uploads.tar.gz -C /data .

Le conteneur auxiliaire monte le volume en lecture seule dans /data et votre répertoire de sauvegarde dans /backup, puis écrit l’archive sur l’hôte. --rm supprime le conteneur auxiliaire dès que tar se termine. Le paramètre :ro est important : une commande tar mal saisie ne peut alors pas endommager la source. -C /data . garantit que la restauration s’effectue au bon emplacement : il enregistre chaque chemin par rapport à la racine du volume. Utilisez plutôt tar czf /backup/uploads.tar.gz /data et chaque chemin commencera par data/. La restauration créera donc /data/data dans le volume, et l’application verra un répertoire vide. L’archive appartient à root, car tar a été exécuté en tant que root dans le conteneur. Exécutez sudo chown "$USER" /srv/backups/myapp/uploads.tar.gz si cela vous pose problème. Consultez aussi comment PUID et PGID déterminent la propriété des fichiers si l’application ne peut pas lire les fichiers restaurés.

Exécutez cette commande une fois par volume nommé. Les bind mounts ne nécessitent aucun conteneur : tar czf /srv/backups/myapp/config.tar.gz -C /srv/myapp/config . effectue la même opération directement sur l’hôte.

Décidez pour chaque volume si l’application doit être arrêtée. Une commande tar exécutée pendant qu’une application réécrit un fichier dans le volume peut capturer ce fichier au milieu de son écriture. Pour un répertoire d’uploads, où les fichiers sont écrits une seule fois puis uniquement lus, le risque est faible. Pour tout le reste, arrêtez le service pendant la copie avec docker compose stop app, puis exécutez docker compose start app. stop laisse les conteneurs et les volumes en place, ce qui correspond exactement au besoin ici. Consultez la différence entre down et stop avant d’exécuter l’une ou l’autre commande.

Ne considérez pas l’archive tar du volume de la base de données comme une sauvegarde de la base de données. Le dump est la sauvegarde. L’archive d’un volume contenant une base de données arrêtée constitue un moyen rapide de reconstruire le service, et rien de plus.

L’ordre des opérations

  1. Copiez les fichiers Compose et le .env dans le répertoire de sauvegarde.
  2. Exportez la base de données tant qu’elle fonctionne.
  3. Arrêtez le conteneur de l’application si ses volumes sont modifiés sur place.
  4. Archivez chaque volume nommé et chaque répertoire monté avec bind mount.
  5. Redémarrez ce que vous avez arrêté, puis vérifiez avec docker compose ps.
  6. Notez les tags et les digests des images utilisés par la stack.
  7. Copiez l’intégralité du répertoire de sauvegarde sur un autre serveur.

C’est l’étape 7 que l’on repousse généralement à plus tard.

Copiez la sauvegarde hors du serveur

Une sauvegarde stockée sur le même disque que la stack vous protège de vos propres erreurs, et de rien d’autre. Une panne de volume, la suppression du serveur ou la perte d’un compte affecte les deux copies en même temps. Envoyez le répertoire vers un stockage qui ne se trouve pas sur ce VPS, selon une planification et avec une politique de rétention. sauvegardes restic depuis un VPS présente la configuration du repository, les options de rétention et la commande de vérification. Il n’est donc pas nécessaire de répéter ces éléments ici.

restic peut également lire le dump directement depuis un pipe. La base de données en clair ne passe ainsi jamais par le disque :

docker compose exec -T db sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' \
  | restic backup --stdin --stdin-filename db.dump

Quel que soit l’outil utilisé, définissez la planification dans un timer systemd ou une tâche cron, et faites en sorte que le job signale les échecs à un endroit que vous consultez. Un script de sauvegarde dont la sortie n’est envoyée nulle part peut cesser de fonctionner pendant six mois sans que personne ne s’en aperçoive.

Démontrer que la sauvegarde fonctionne avec un exercice de restauration

Une sauvegarde que personne n’a jamais restaurée reste une hypothèse. L’exercice ci-dessous restaure la sauvegarde dans une seconde stack exécutée à côté de la première. La production continue ainsi de répondre aux requêtes, et aucune commande saisie ne peut l’atteindre.

Le mécanisme repose sur le nom du projet. Compose le déduit du nom du répertoire et l’appose à chaque conteneur et volume qu’il crée. Copiez la sauvegarde dans un nouveau répertoire : la stack restaurée obtient automatiquement ses propres volumes.

sudo install -d -m 700 -o "$USER" -g "$(id -gn)" /srv/myapp-restore
cd /srv/myapp-restore
cp /srv/backups/myapp/compose.yaml /srv/backups/myapp/.env .

Modifiez le fichier Compose copié afin que le port publié sur l’hôte ne puisse pas entrer en conflit avec la stack en cours d’exécution : remplacez 18080:8080 par 8080:8080, ou modifiez dans le fichier .env copié la variable qui définit ce port. Créez ensuite les conteneurs et leurs volumes vides sans rien démarrer :

docker compose create
docker volume ls --filter label=com.docker.compose.project=myapp-restore

La deuxième commande doit afficher les mêmes noms de volumes que ceux de la production, avec myapp-restore_ devant. Remplissez-les, démarrez uniquement la base de données, puis chargez le dump :

docker run --rm -v myapp-restore_uploads:/data -v /srv/backups/myapp:/backup \
  alpine:3 tar xzf /backup/uploads.tar.gz -C /data
docker compose up -d db
docker compose exec -T db sh -c \
  'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists' \
  < /srv/backups/myapp/db-2026-08-16.dump

--clean --if-exists supprime chaque objet avant de le recréer, ce qui rend la restauration répétable. Sans cette option, une deuxième exécution dans une base de données qui contient déjà ces tables s’arrête avec pg_restore: error: could not execute query: ERROR: relation "users" already exists.

Démarrez ensuite le reste de la stack et vérifiez son fonctionnement comme le ferait un utilisateur :

docker compose up -d --wait
docker compose exec -T db sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "\dt"'
docker compose logs --tail=50

docker compose up -d --wait attend que chaque service soit signalé comme en cours d’exécution ou healthy. La commande se termine avec un code différent de zéro si un service n’atteint jamais cet état, ce qui rend cette étape scriptable. Lorsqu’un service n’atteint jamais l’état healthy, docker compose ps affiche son état. Les healthchecks de Compose expliquent ce que lit cette colonne. Ouvrez ensuite l’application sur le port alternatif et connectez-vous avec un compte réel. Créez un enregistrement et ouvrez un fichier stocké dans un volume. Cet ensemble constitue la preuve : le dump a été restauré, le volume a été restauré et les deux concordent. Un exercice qui vérifie uniquement l’affichage de la page de connexion ne prouve rien concernant vos données.

Supprimez l’environnement de test une fois l’exercice réussi :

docker compose down -v

C’est le seul cas où -v est l’option correcte. Dans le répertoire de production, la même commande supprime les volumes que vous essayez de protéger.

Mettre à niveau une stack Compose

Lisez les notes de version de chaque version comprise entre celle que vous utilisez et celle vers laquelle vous voulez passer. Recherchez-y les termes breaking et migration. Les projets qui ne prennent pas en charge le passage direct entre plusieurs versions majeures l’indiquent à cet endroit. Une migration qui refuse de s’exécuter ne vous en informe qu’après avoir déjà modifié une partie du schéma.

Notez ce que vous utilisez actuellement avant toute modification :

docker compose images
docker image inspect --format '{{index .RepoDigests 0}}' postgres:16.4

docker compose images répertorie l’image et le tag utilisés actuellement par chaque service. Seul le digest identifie une image de manière exacte, car un tag peut être déplacé à tout moment pour pointer vers une autre image.

Reprenez la sauvegarde des sections précédentes et copiez-la hors du serveur. Faites-le également pour une mise à jour corrective. Les mises à niveau simples sont précisément celles pour lesquelles on cesse de se préparer.

Épinglez ensuite la version dans le fichier Compose, car latest n’est pas une version :

services:
  db:
    image: postgres:16.4

Avec image: postgres:latest, docker compose pull récupère ce vers quoi ce tag pointe aujourd’hui, et vous ne pouvez pas identifier précisément ce que vous utilisiez hier. Un tag épinglé transforme la mise à niveau en une modification d’une seule ligne, lisible dans git diff et réversible avec une autre modification. Épinglez l’image de l’application de la même manière, en utilisant la version exacte indiquée sur la page de version du projet.

Téléchargez les images et recréez les conteneurs :

docker compose pull
docker compose up -d --wait

docker compose up -d compare le fichier aux conteneurs en cours d’exécution et recrée uniquement les services dont l’image ou la configuration a changé. Il ne modifie pas les volumes nommés. Le nouveau conteneur démarre donc avec les données existantes. C’est l’objectif de l’opération, mais aussi son principal risque, car la première phase de démarrage de la nouvelle version est généralement celle où s’exécute la migration du schéma.

Surveillez l’opération :

docker compose ps
docker compose logs -f --tail=100 app

Un conteneur qui a échoué affiche Exited (1) dans la colonne STATUS de docker compose ps. La cause figure dans les dernières lignes de son journal. Les erreurs de migration y sont clairement visibles, mais restent invisibles ailleurs. Lorsque les journaux se stabilisent, connectez-vous et utilisez l’application pendant une minute.

Si docker compose pull s’arrête avec no space left on device, la présence d’anciennes couches d’image en est généralement la cause. La suppression des images Docker inutilisées permet de récupérer l’espace. Effectuez cette suppression après avoir confirmé que la mise à niveau fonctionne, et non avant, car ces anciennes couches sont nécessaires pour effectuer rapidement un rollback.

Comment revenir en arrière lorsque la mise à niveau échoue

Il existe deux cas, dont le coût est très différent. Si la nouvelle version n’a pas modifié le schéma, le rollback tient en une ligne : remettez l’ancien tag dans le fichier Compose et exécutez docker compose up -d. Le conteneur est remplacé, les volumes restent en place et l’ancien code lit les données qu’il a écrites.

Si la nouvelle version a migré le schéma, l’ancien code ne peut plus le lire. Les migrations sont conçues pour s’exécuter vers l’avant, et la plupart des projets ne fournissent aucun script de downgrade. L’ancienne version démarre alors, puis échoue à la première requête qui porte sur une colonne renommée ou supprimée, avec des erreurs de la forme ERROR: column "avatar_url" does not exist. Pour revenir en arrière, utilisez le dump créé avant le pull : remettez l’ancien tag, retirez le volume de la base de données, recréez-le vide, restaurez le dump et démarrez le service. Sans ce dump, il n’existe aucun retour en arrière possible. C’est précisément pour cette raison que la sauvegarde doit précéder le pull.

Les versions majeures de Postgres représentent le cas le plus sensible. Elles surprennent, car l’échec survient lors de la mise à niveau et non lors du rollback. Le format sur disque change à chaque version majeure. Remplacez postgres:16.4 par postgres:17.2, exécutez docker compose up -d, et le nouveau serveur refuse de démarrer :

FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 17.2.

L’image n’exécute pas pg_upgrade automatiquement. Dans une stack Compose, la procédure prise en charge consiste à effectuer un dump, remplacer la version, puis restaurer les données : créez le dump pendant que l’ancienne version fonctionne encore, docker compose down, supprimez le volume de la base de données, définissez le nouveau tag, exécutez docker compose create pour créer un répertoire de données vide, démarrez la base de données, restaurez le dump, puis démarrez le reste de la stack. Conservez l’ancien dump jusqu’à ce que la nouvelle version majeure ait traité du trafic réel pendant une journée. Les mises à niveau mineures au sein d’une même version majeure, de 16.4 à 16.9, ne nécessitent aucune de ces étapes, car le format reste stable et le conteneur démarre simplement.

Les snapshots de VPS sont-ils des sauvegardes ?

Ils complètent une sauvegarde, mais les deux échouent de manière différente. Un snapshot copie l’intégralité du disque au niveau de l’hyperviseur. Il permet donc de restaurer toute la machine en quelques minutes, y compris les éléments que vous avez oublié de sauvegarder. C’est l’outil adapté à un cas précis : la mise à niveau a rendu le serveur inutilisable et vous voulez le retrouver tel qu’il était vingt minutes plus tôt.

Pour tout le reste, c’est un outil peu adapté. La granularité est celle de la machine entière. Pour récupérer une seule table supprimée, vous devez donc restaurer tout un serveur quelque part, puis en extraire la table. La durée de rétention est généralement courte. Les copies sont normalement stockées dans le même compte fournisseur que le serveur. La perte du compte entraîne donc la perte du serveur et de ses snapshots. Enfin, un snapshot d’une machine en fonctionnement peut capturer la base de données au milieu d’une écriture. La base effectue alors une récupération après incident lors de son premier démarrage, et toute transaction encore en cours est perdue.

Utilisez les deux. Le snapshot sert de bouton d’annulation pendant une fenêtre de mise à niveau. Le dump est la copie qui survit à la suppression du compte. la différence entre snapshots et sauvegardes explique quelles défaillances chacun couvre réellement. Ce même répertoire de sauvegarde permet aussi de transformer la migration d’une stack vers un nouveau VPS en opération courante, plutôt qu’en reconstruction de mémoire.

Ce qui peut mal se passer et ce que vous verrez

L’option volumes avec down. docker compose down -v supprime les volumes nommés déclarés dans le fichier, et Compose le confirme avec une ligne contenant Volume myapp_db_data Removed. Il n’y a aucun retour en arrière. La commande simple docker compose down les laisse intacts. Saisissez la forme longue, docker compose down --volumes, afin de devoir écrire entièrement l’option destructive.

Un dump sans chaîne magique. pg_restore: error: did not find magic string in file header signifie que le fichier n’est pas une archive. La cause habituelle est l’absence de -T sur docker compose exec, car avec un TTY attaché, le flux est traduit avant d’arriver dans votre shell et le dump binaire est corrompu. Recréez le dump avec -T, puis vérifiez ses 5 premiers octets avec head -c 5.

Un mot de passe qui ne change pas. FATAL: password authentication failed for user "appuser" après une restauration signifie que .env et le répertoire de données proviennent de moments différents. L’image définit ce mot de passe uniquement lorsqu’elle crée un répertoire de données vide. Modifier .env ensuite ne change donc rien dans la base de données. Restaurez le .env correspondant ou modifiez le mot de passe dans la base de données avec ALTER USER.

Un deuxième volume vide. Docker crée un volume à la demande. Ainsi, docker run -v myapp_upload:/data avec s manquant écrit dans un nouveau volume vide et indique que l’opération a réussi. docker volume ls affiche ensuite les 2 noms, dont 1 ne contient rien. Copiez les noms des volumes depuis docker volume ls au lieu de les saisir de mémoire.

Une restauration lancée sur la production. Exécuter les commandes de restauration dans /srv/myapp au lieu de /srv/myapp-restore écrase les données en production avec la sauvegarde. Les commandes sont identiques dans les 2 environnements. Vérifiez pwd avant chaque commande de restauration et conservez l’exercice dans son propre répertoire.

FAQ

docker compose down supprime-t-il mes données ?

Non. docker compose down supprime les conteneurs et le réseau par défaut, mais ne modifie pas les volumes nommés ni les bind mounts. docker compose down -v supprime les volumes nommés déclarés dans votre fichier, et cette opération est définitive. Les bind mounts correspondent à des répertoires de l’hôte ; Compose ne les supprime donc jamais. Si vous voulez arrêter les services pendant une sauvegarde sans modifier le reste, utilisez plutôt docker compose stop.

Puis-je copier le répertoire de données Postgres au lieu d’exécuter pg_dump ?

Uniquement lorsque le conteneur est arrêté. Tant que le serveur fonctionne, ses fichiers changent pendant la copie. Celle-ci peut donc contenir un mélange d’états qui ne pourra pas être restauré correctement. Une copie au niveau des fichiers dépend également d’une seule version majeure de Postgres. Elle ne démarrera donc pas avec une autre version. Arrêtez le conteneur, archivez le volume, redémarrez-le, puis considérez cette copie comme une méthode de reconstruction rapide et non comme votre seule sauvegarde. Le dump est la copie portable, et celle que vous devez utiliser pour la restauration.

Comment mettre à niveau Postgres vers une nouvelle version majeure dans Compose ?

Modifier le tag ne suffit pas. Le nouveau serveur refuse de démarrer avec l’ancien répertoire de données et journalise The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 17.2. Exécutez pg_dump avec l’ancienne version encore active, puis docker compose down. Supprimez le volume de la base de données, définissez le nouveau tag, exécutez docker compose create pour créer un volume vide, démarrez la base de données, puis restaurez le dump dans ce volume. Conservez l’ancien dump jusqu’à ce que la nouvelle version ait traité du trafic réel.

À quelle fréquence les sauvegardes doivent-elles être exécutées et combien de temps dois-je les conserver ?

Adaptez l’intervalle à la quantité de travail que vous acceptez de refaire. Une sauvegarde quotidienne convient à une stack personnelle ou à une petite équipe. Ajoutez une sauvegarde manuelle juste avant toute mise à niveau. Pour la rétention, conservez suffisamment d’historique pour couvrir les dommages que vous ne remarquez pas immédiatement. Une table corrompue découverte vendredi ne peut pas être récupérée avec la copie de jeudi soir. restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune constitue une bonne base. Quel que soit le planning, effectuez une restauration une fois par trimestre. Tant que vous ne l’avez pas fait, vous n’avez pas de sauvegardes : vous avez des fichiers.

Dois-je arrêter toute la stack pour effectuer une sauvegarde ?

Généralement, non. Le dump de la base de données reste cohérent pendant que le serveur fonctionne. La base de données ne nécessite donc aucune interruption. La question concerne les volumes. Si l’application ajoute uniquement des fichiers, par exemple dans un répertoire d’uploads, une archive à chaud est suffisamment sûre. Si elle réécrit les fichiers sur place, arrêtez ce service pendant la copie avec docker compose stop app, puis redémarrez-le ensuite. Arrêter l’application tout en laissant la base de données fonctionner constitue généralement la fenêtre d’interruption sûre la plus courte possible.