Files
maj-stack-compose/README.md
T
2026-10-02 09:43:36 +02:00

6.0 KiB

maj-stack-compose

Script shell qui parcourt toutes les stacks docker compose d'un répertoire racine, détecte celles dont au moins une image a une nouvelle version, et les relance proprement (down puis up -d).

Structure du script

Principe

Chaque sous-répertoire de la racine (par défaut /home) contenant un fichier compose est une stack :

/home
├── freshrss/        compose.yaml          → stack « freshrss »
├── gitea/           docker-compose.yml    → stack « gitea »
├── immich/          compose.yml           → stack « immich »
└── notes/           (pas de fichier compose → ignoré)

Pour chaque stack, le script :

  1. vérifie le fichier compose avec docker compose config -q :
    • fichier vide → stack ignorée sans rien afficher ;
    • fichier invalide → erreur affichée en rouge ;
  2. ignore les stacks arrêtées (sauf avec -a), pour ne pas démarrer ce qui a été coupé volontairement ;
  3. télécharge les images avec docker compose pull. Cette étape ne touche pas aux conteneurs qui tournent ;
  4. compare, pour chaque conteneur, l'image qu'il utilise avec l'image qui vient d'être téléchargée pour le même tag ;
  5. si au moins une image a changé (ou avec -f), relance toute la stack : docker compose down puis docker compose up -d.

Les fichiers compose reconnus sont, dans cet ordre : compose.yaml, compose.yml, docker-compose.yaml, docker-compose.yml.

Prérequis

  • Linux avec Docker et Docker Compose v2 (commande docker compose) ;
  • flock (paquet util-linux, présent sur toutes les distributions courantes) ;
  • un utilisateur ayant accès à Docker (root ou membre du groupe docker).

Installation

git clone https://gitea.vlab.bzh/vLab-BZH/maj-stack-compose.git
cd maj-stack-compose
chmod +x update-stacks.sh

Utilisation

update-stacks.sh [-v | -q] [-n] [-f] [-p] [-a] [RACINE]
Option Effet
-v verbose : détaille chaque conteneur (image actuelle → nouvelle), chaque commande docker et sa sortie
-q quiet : une seule ligne par stack (nom, répertoire, état)
-n dry-run : détecte les mises à jour mais ne relance rien
-f force : down + up -d de chaque stack, même sans mise à jour
-p prune : supprime les images orphelines à la fin (docker image prune -f)
-a all : traite aussi les stacks arrêtées (sinon elles sont ignorées)
-h affiche l'aide
RACINE répertoire contenant les stacks (défaut : /home)

Exemples

Voir ce qui serait mis à jour, sans rien toucher :

./update-stacks.sh -n /home

Mettre à jour, avec un affichage minimal :

./update-stacks.sh -q /home

Mettre à jour, puis supprimer les anciennes images :

./update-stacks.sh -p /home

Relancer toutes les stacks, y compris celles qui sont arrêtées :

./update-stacks.sh -f -a /home

Affichage

Couleurs

Couleur Signification
🟢 vert stack à jour
🟡 jaune mise à jour détectée, appliquée (ou à faire en dry-run), ou redémarrage forcé
🔴 rouge erreur (fichier compose invalide, échec du pull, du down ou du up -d)
gris stack arrêtée, ignorée

Les couleurs sont désactivées automatiquement quand la sortie n'est pas un terminal (cron, redirection vers un fichier), ou si la variable NO_COLOR est définie.

Mode quiet (-q)

arcane          /home/arcane          ✔ à jour
arcane-agent    /home/arcane-agent    arrêtée
freshrss        /home/freshrss        ✔ à jour
immich          /home/immich          ↑ mise à jour appliquée
broken          /home/broken          ✘ erreur (fichier compose invalide)
      yaml: line 3: mapping values are not allowed

Mode normal (par défaut)

[2026-10-02 04:00:01] Racine : /home
[2026-10-02 04:00:01] == Stack : immich (/home/immich/compose.yml)
[2026-10-02 04:00:09]     ↑ immich-server (ghcr.io/immich-app/immich-server:release) : nouvelle image disponible
[2026-10-02 04:00:31]     ✔ stack relancée (down + up -d) : mise à jour
[2026-10-02 04:00:31] Terminé. Stacks relancées : 1 immich | Échecs : 0

Mode verbose (-v)

Ajoute l'état de chaque conteneur avec les identifiants courts des images, ainsi que chaque commande docker ($ docker compose pull …) suivie de sa sortie complète.

En mode normal et quiet, la sortie de docker est masquée ; elle n'est affichée, sous la stack concernée, qu'en cas d'échec.

Automatisation (cron)

Exemple : chaque nuit à 4 h, avec nettoyage des images et journal dans /var/log (crontab de root) :

0 4 * * * /opt/maj-stack-compose/update-stacks.sh -p /home >> /var/log/update-stacks.log 2>&1

Un verrou (/tmp/update-stacks.lock) empêche deux exécutions simultanées.

Code de retour

Code Signification
0 toutes les stacks ont été traitées sans erreur
1 au moins une stack en erreur, une autre exécution en cours, Docker Compose v2 absent ou racine introuvable

Limites

  • Tags figés : seules les nouvelles images publiées sous le même tag sont détectées (latest, release, 16…). Une image figée sur nginx:1.25.3 ne passera jamais en 1.25.4 : changer de version reste une décision manuelle.
  • Images construites localement : les services avec build: sont ignorés au pull (--ignore-buildable) ; ils ne déclenchent donc pas de mise à jour.
  • Coupure de service : down puis up -d arrête toute la stack quelques secondes, y compris les conteneurs dont l'image n'a pas changé.
  • Profondeur : seuls les sous-répertoires directs de la racine sont examinés.

Documentation