157 lines
6.0 KiB
Markdown
157 lines
6.0 KiB
Markdown
# 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`).
|
|
|
|

|
|
|
|
## 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
|
|
|
|
```bash
|
|
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 :
|
|
|
|
```bash
|
|
./update-stacks.sh -n /home
|
|
```
|
|
|
|
Mettre à jour, avec un affichage minimal :
|
|
|
|
```bash
|
|
./update-stacks.sh -q /home
|
|
```
|
|
|
|
Mettre à jour, puis supprimer les anciennes images :
|
|
|
|
```bash
|
|
./update-stacks.sh -p /home
|
|
```
|
|
|
|
Relancer toutes les stacks, y compris celles qui sont arrêtées :
|
|
|
|
```bash
|
|
./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
|
|
|
|
- [`docs/architecture.png`](docs/architecture.png) : schéma de fonctionnement du script ;
|
|
- [`docs/architecture.excalidraw`](docs/architecture.excalidraw) : source du schéma, modifiable sur [excalidraw.com](https://excalidraw.com) (menu *Ouvrir*).
|