--- title: Docker Auto-Updates url: https://blog.guigpap.com/fr/workflows/docker-updates/ url_md: https://blog.guigpap.com/fr/workflows/docker-updates.md category: automation date: '2026-01-20' maturite: production techno: - docker - n8n - telegram application: - automation - operations --- # Docker Auto-Updates > Mises à jour automatiques des images Docker via DIUN, refactorisé en hub 36 nodes + 3 sub-workflows avec version tracking ## 1. Quoi ? — Définition et contexte Le workflow **Docker Auto-Updates** automatise la mise à jour des images Docker du VPS. DIUN détecte les nouvelles versions disponibles, le hub N8N classifie chaque image (critical / base / applicatif), et un sous-workflow exécute le cycle complet : backup, pull/build, health check, rollback si nécessaire, notification. > **Note - DIUN** > > **DIUN** (Docker Image Update Notifier) compare les digests des images en cours d'exécution avec ceux disponibles sur les registres Docker. Il ne télécharge pas l'image complète — seul le digest est comparé, ce qui permet une vérification rapide toutes les 6 heures sans coût significatif. ### Architecture refactorée (#275) | Workflow | ID | Nodes | Rôle | |----------|------|-------|------| | **Docker DIUN** (parent) | `WdSepRkceMzI0QQ5` | 36 | Triggers, routage par catégorie, classification | | **DIUN Update Executor** (SW-1) | `VSFJv2DbdkvQ2cl1` | 25 | Lifecycle partagé : backup, update, health check, rollback, notify | | **DIUN Queue Processor** (SW-2) | `Eb3QIk8DnEQIXeSl` | 6 | Boucle de traitement de la queue 03h-05h | | **DIUN Approval Handler** (SW-3) | `JLsR7JSMAQDwzqEX` | 20 | Classification, approbation, rejet, report Telegram | Avant le refactoring #275, ce workflow comptait 101 nodes monolithiques. La séparation en hub + 3 sous-workflows permet de tester chaque cycle isolément et de réutiliser le DIUN Update Executor depuis d'autres déclencheurs (rebuild manuel, file provider). ### Architecture visuelle ```mermaid flowchart TD subgraph Triggers["Déclencheurs"] direction TB DIUNHook["DIUN webhook · 6h scan"] FileProvider["File Provider · base images"] Cron3h["Cron 03h · queue processor"] Manual["Manual rebuild"] end subgraph Hub["Docker DIUN · 36 nodes"] direction TB Receive["Webhook"] Lookup["Lookup image_policies"] Classify["Classify · critical / base / applicatif"] end subgraph SW3["SW-3 Approval Handler · 20 nodes"] direction TB Notify["Notification Hub · approval"] Wait["Wait for callback · approve/reject/later"] Decision["Switch decision"] end subgraph SW1["SW-1 Update Executor · 25 nodes"] direction TB Backup["Backup if needed"] Pull["Pull or Build"] Up["compose up -d"] Health["Health check 2 min"] Rollback["Rollback if KO"] NotifyOK["Notification Hub · success/failure"] end subgraph SW2["SW-2 Queue Processor · 6 nodes"] direction TB LoopQueue["Loop pending_updates"] CallExec["Call Update Executor"] end Triggers --> Receive --> Lookup --> Classify Classify -->|critical| SW1 Classify -->|base| Queue["Insert pending_updates"] Classify -->|applicatif| SW3 Queue -.->|03h-05h| Cron3h Cron3h --> SW2 --> CallExec --> SW1 SW3 -->|approved| SW1 SW3 -->|rejected/later| Notify SW1 --> NotifyOK ``` ### Catégories d'images | Catégorie | Comportement | Exemples | |-----------|--------------|----------| | **critical** | Update immédiat + health check | caddy, crowdsec, security-stack | | **base** | Queue pour fenêtre 03h-05h | postgres, redis, prometheus | | **applicatif** | Approbation admin requise via Telegram | n8n, odoo, grafana, ai-stack | --- ## 2. Pourquoi ? — Enjeux et motivations ### Problèmes résolus | Problème | Sans ce workflow | Avec ce workflow | |----------|------------------|------------------| | **Images obsolètes** | Vulnérabilités non patchées | Updates automatiques selon politique | | **Downtime utilisateur** | Updates en pleine journée | Fenêtre de maintenance nocturne | | **Updates risqués** | Pas de validation préalable | Approbation pour les apps critiques | | **Rollback manuel** | Intervention tardive | Health check + rollback automatique | | **Pas de visibilité versions** | "Quelque chose a changé" | Version tracking before/after dans la notif | ### Pourquoi trois catégories ? | Catégorie | Justification | |-----------|---------------| | **critical** | Sécurité prioritaire, update immédiat (Caddy = point d'entrée) | | **base** | Infra stable, update nocturne pour minimiser l'impact | | **applicatif** | Business-critical, validation humaine requise | > **Tip - Fenêtre de maintenance** > > Les images "base" sont mises à jour entre 3h et 5h du matin pour minimiser l'impact. Le workflow Queue Processor traite la table `pending_updates` dans cette fenêtre, en série pour éviter de saturer le VPS. ### Pourquoi un sub-workflow Update Executor partagé ? Le cycle d'update (backup → pull/build → up → health check → rollback / notify) est identique quelle que soit la cause du déclenchement. L'extraction en SW-1 permet : | Bénéfice | Détail | |----------|--------| | **Réutilisation** | Mêmes garanties pour DIUN, file provider, rebuild manuel | | **Tests isolés** | Mockable indépendamment du trigger | | **Maintenance** | Un seul endroit où changer la stratégie de health check | --- ## 3. Comment ? — Mise en œuvre technique ### Data Tables #### `image_policies` — Politique par image | Colonne | Type | Description | |---------|------|-------------| | `image_key` | Text | Clé unique : `project/service` | | `category` | Text | critical / base / applicatif | | `backup` | Boolean | Backup requis avant update | | `custom_build` | Boolean | Image custom (build vs pull) | | `github_repo` | Text | owner/repo pour changelog | | `compose_dir` | Text | Chemin absolu du docker-compose | #### `pending_updates` — Queue 03h-05h | Colonne | Type | Description | |---------|------|-------------| | `image_key` | Text | Clé unique | | `image` | Text | Nom complet de l'image | | `project` | Text | Nom du projet | | `service` | Text | Nom du service | | `custom_build` | Boolean | Build au lieu de pull | | `created_at` | Text | Timestamp ISO | #### `pending_updates_approvals` — Approbations en attente Approbations applicatives en attente de réponse Telegram. TTL 7j ; au-delà, l'approbation est automatiquement requestée à nouveau au prochain scan. ### Commandes Docker générées ```bash # Image standard docker compose -f /path/to/stack/docker-compose.yaml pull docker compose -f /path/to/stack/docker-compose.yaml up -d # Image custom (custom_build = true) docker compose -f /path/to/stack/docker-compose.yaml pull --ignore-buildable docker compose -f /path/to/stack/docker-compose.yaml build --no-cache docker compose -f /path/to/stack/docker-compose.yaml up -d ``` ### Flow d'approbation (images applicatives) ```mermaid flowchart TD Detect["Image applicative détectée"] Notif["Notification Hub · approval_request"] Buttons["Boutons inline · Approve / Reject / Later"] CB["NH Callback Handler"] ApprovalSW["SW-3 Approval Handler"] Decision["Switch decision"] Approve["approved"] Reject["rejected"] Later["later → pending_updates"] Run["SW-1 Update Executor"] Skip["Notify · Skipped"] Queue["Queue 03h-05h"] Detect --> Notif --> Buttons Buttons --> CB --> ApprovalSW --> Decision Decision --> Approve --> Run Decision --> Reject --> Skip Decision --> Later --> Queue ``` ### Health check post-update Après chaque update, SW-1 vérifie pendant 2 minutes que les conteneurs sont healthy : ```bash docker compose -f /path/to/stack/docker-compose.yaml ps --format json ``` Si un conteneur reste `unhealthy` après 120 s, un rollback est déclenché : `docker compose pull ` puis `up -d`. Une notification critical est envoyée au Hub avec le détail du diagnostic. ### Self-update Docker (n8n-stack) Updater **N8N lui-même** est délicat : le workflow d'update tourne dans le container qu'il met à jour. Le pattern self-restart utilisé : | Étape | Action | |-------|--------| | 1 | Insert flag de maintenance dans `error_handling_config` (suppress notifications) | | 2 | Déclencher un script externe via `nohup` qui attend 10s puis `docker compose up -d --force-recreate` | | 3 | Le workflow N8N s'arrête (le container redémarre) | | 4 | Au redémarrage, un workflow de cleanup retire le flag de maintenance et notifie le succès | > **Caution - Pourquoi `nohup`** > > Sans `nohup`, le `compose up -d` serait tué quand le container N8N s'arrête, laissant le service en état partiel. `nohup` détache le processus du container, ce qui permet le redémarrage propre. ### Version tracking Chaque update capture les versions avant/après pour traçabilité. Le format utilise des marqueurs SSH pour extraire les versions du Dockerfile ou du `image:tag` : ``` n8n-custom:latest 2.4.8 → 2.5.0 caddy-crowdsec:latest 2.8.4 → 2.8.5 ``` Les notifications Telegram affichent la transition de version, ce qui permet de voir d'un coup d'œil la nature du changement (patch, minor, major). ### File Provider Auto-Rebuild Quand une **image de base** change (`node:20-slim`, `caddy:builder`...), les images custom qui en dépendent doivent être reconstruites. DIUN surveille ces images via son provider `file` (lecture du `base-images.yml`), et le workflow détecte la dépendance. | Image de base | Service custom | Catégorie | |---------------|----------------|-----------| | `caddy:builder`, `caddy:latest` | security-stack/caddy | critical (rebuild immédiat) | | `n8nio/n8n:latest` | n8n-stack/n8n | applicatif (approbation requise) | | `node:20-slim`, `ghcr.io/astral-sh/uv` | ai-stack/cli-ollama | applicatif (approbation requise) | > **Caution - Rebuild N8N** > > Un rebuild N8N entraîne aussi le rebuild des 5 workers. Le workflow utilise le pattern self-restart avec flag de maintenance dans `error_handling_config` pour éviter les fausses alertes du Global Error Handler pendant le redémarrage. ### Incident Response (AI-Assisted) Quand Prometheus Alertmanager signale un problème (conteneur down, CPU spike, disk full), un workflow Incident Response déclenche un diagnostic Claude : | Sévérité | Comportement | |----------|--------------| | **TRIVIAL** | Auto-remediation (restart) + health check + notification | | **MODERATE** | Claude propose + exécute le fix, monitoring 5 min | | **COMPLEX** | Claude génère un plan, attente d'approbation humaine (timeout 30 min) | Pour les cas COMPLEX, Claude produit un plan détaillé envoyé sur Telegram avec boutons `[Exécuter]` `[Modifier]` `[Ignorer]`. C'est le même pattern Plan Engine que le Système Conversationnel. ### Commandes utiles ```bash # Forcer un check DIUN docker exec diun diun --test # Logs DIUN docker logs diun --tail 50 # Voir les politiques configurées # N8N → Data → Tables → image_policies (26 entries actuelles) # Voir les updates en attente # N8N → Data → Tables → pending_updates ``` --- ## 4. Et si ? — Perspectives et limites ### Limites actuelles | Limite | Impact | Mitigation | |--------|--------|------------| | **Pas de tests automatiques** | Risque de régression non détectée | Health check basique uniquement | | **Rollback manuel possible** | Si rollback échoue, intervention requise | Notification immédiate avec contexte | | **Dépendance DIUN** | Pas de détection si DIUN down | Monitoring du conteneur via Health Check | | **Pas de canary** | Update direct, pas de progressive rollout | Acceptable sur un VPS solo | ### Scénarios d'évolution **Si un update cause une régression** : - Health check détecte le problème - Rollback automatique vers l'image précédente - Notification avec détails pour investigation **Si les updates sont trop fréquents** : - Ajuster le polling DIUN (actuellement 6h) - Créer une catégorie "stable" avec updates mensuels - Filtrer par semantic versioning (major uniquement) **Si besoin de tests plus poussés** : - Smoke tests post-update via la stack `monitoring-stack` - Délai d'observation avant notification success - Environnement staging dédié pour tests préalables (coût VPS supplémentaire) **Si couplage CVE plus fort souhaité** : - Refuser un update qui introduirait une nouvelle CRITICAL non corrigée - Utiliser la veille [Security CVE Watch](/fr/workflows/security-cve-watch/) comme gating --- ## Pages liées ### Infrastructure - [Architecture VPS](/fr/infrastructure/architecture-vps/) — Vue d'ensemble - [Notify Stack](/fr/infrastructure/notify-stack/) — DIUN qui déclenche les updates - [Security Stack](/fr/infrastructure/security-stack/) — Caddy protégé contre restart accidentel ### Workflows - [Telegram Orchestrator](/fr/workflows/telegram-orchestrator/) — Réception des approbations - [Notification Hub](/fr/workflows/notification-hub/) — Routage des notifications de succès / échec - [Security CVE Watch](/fr/workflows/security-cve-watch/) — Couplage scan CVE pré-update - [Error Handler](/fr/workflows/error-handler/) — Capture des erreurs DIUN ### Référence - [Glossaire](/fr/reference/glossary/) — DIUN, Health Check, Self-restart, File Provider ## Metadonnees agent - Cet article est issu du blog GuiGPaP Lab. - Contexte global du blog: https://blog.guigpap.com/llms.txt - Contact auteur: https://odoo.guigpap.com/mon-cv - Licence: CC-BY-SA 4.0