--- title: 'Notify Stack : DIUN + ntfy' url: https://blog.guigpap.com/fr/infrastructure/notify-stack/ url_md: https://blog.guigpap.com/fr/infrastructure/notify-stack.md category: infrastructure date: '2026-05-04' maturite: production techno: - docker - n8n application: - infrastructure - operations --- # Notify Stack : DIUN + ntfy > Surveillance des mises à jour d'images Docker et notifications push self-hosted ## 1. Quoi ? — Définition et contexte La **Notify Stack** centralise deux briques de notification de l'infrastructure : | Composant | Rôle | Image | |-----------|------|-------| | **DIUN** | Détecteur de mises à jour d'images Docker | `crazymax/diun` | | **ntfy** | Serveur de notifications push self-hosted | `binwiederhier/ntfy` | > **Note - Pourquoi les deux ensemble** > > DIUN ne notifie pas directement sur mobile : il déclenche un webhook qui est consommé par un workflow N8N. ntfy fournit le canal mobile (et le canal de fallback monitoring) côté sortie de la chaîne. Les deux services partagent le même thème "notification", mais ils ne se parlent pas directement aujourd'hui. ### Architecture visuelle ```mermaid flowchart TD Socket["/var/run/docker.sock"] BaseImages["base-images.yml · file provider"] subgraph Notify["notify-stack"] direction TB DIUN["DIUN · scan toutes les 6 h"] NTFY["ntfy · auth deny-all"] end subgraph N8N["N8N · workflow Docker DIUN"] direction TB HubWebhook["/webhook/notify/image-update"] Router["Router · critical / base / applicatif"] Updater["DIUN Update Executor"] end subgraph Sortie["Canaux de notification"] direction TB Telegram["Telegram"] Discord["Discord"] Mobile["Mobile · ntfy app"] end Socket --> DIUN BaseImages --> DIUN DIUN -->|webhook Bearer| HubWebhook DIUN -->|webhook| Discord HubWebhook --> Router --> Updater Updater --> Telegram Updater --> NTFY NTFY --> Mobile ``` --- ## 2. Pourquoi ? — Enjeux et motivations ### Pourquoi DIUN plutôt que Watchtower ou Docker Hub UI ? | Critère | DIUN | Watchtower | Docker Hub UI | |---------|------|------------|---------------| | **Détection sans pull** | Oui (compare digests) | Non (pull pour vérifier) | Manuel | | **Auto-update** | Non (notification only) | Oui (mais aveugle) | Non | | **File provider** | Oui (images de base custom) | Non | Non | | **Webhook personnalisable** | Oui (Bearer auth) | Non | Non | | **Exclusion par label** | Oui | Oui | N/A | **Critères de décision :** 1. **Découpler détection et mise à jour** — Watchtower applique aveuglément, DIUN notifie et délègue la décision à un workflow N8N qui peut classifier (critical / base / applicatif) et demander une approbation Telegram. 2. **Surveiller les images de base des Dockerfiles custom** — Le file provider permet de détecter qu'une nouvelle version de `caddy:builder` est sortie alors qu'aucun container ne tourne directement avec cette image. 3. **Pas de pull inutile** — DIUN compare les digests via l'API du registre, sans télécharger l'image entière. ### Pourquoi ntfy plutôt que Pushover ou Slack ? > **Tip - ntfy en bref** > > **ntfy** est un serveur Pub/Sub HTTP minimaliste : on POST un message sur `https://ntfy.example.com/`, et tout client souscrit à ce topic le reçoit. L'app mobile officielle (Android/iOS) écoute en arrière-plan et affiche les notifications natives. | Critère | ntfy self-hosted | Pushover | Slack | |---------|------------------|----------|-------| | **Coût** | Gratuit (VPS) | Payant à l'app | Gratuit / payant | | **Souveraineté** | Données chez moi | SaaS | SaaS | | **API simple** | curl HTTP | API propriétaire | API propriétaire | | **Auth** | Token + user/pass | Token | OAuth + tokens | | **Multi-canaux** | Topics | Devices | Channels | L'objectif est d'avoir un canal de notification **séparé de Telegram** pour les alertes monitoring (Alertmanager, Grafana). Telegram est utilisé pour l'interactif (workflows N8N, approbations) ; ntfy pour les push silencieux côté mobile. --- ## 3. Comment ? — Mise en œuvre technique ### Configuration DIUN Le service tourne sans interface, configuré entièrement par variables d'environnement. ```yaml # notify-stack/docker-compose.yaml (extrait DIUN) diun: image: crazymax/diun:latest volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - notify-diun-data:/data - ./diun/base-images.yml:/config/base-images.yml:ro environment: - DIUN_WATCH_WORKERS=10 - DIUN_WATCH_SCHEDULE=0 */6 * * * - DIUN_WATCH_FIRSTCHECKNOTIF=false - DIUN_PROVIDERS_DOCKER=true - DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=true - DIUN_PROVIDERS_DOCKER_WATCHSTOPPED=false - DIUN_PROVIDERS_FILE_FILENAME=/config/base-images.yml - DIUN_NOTIF_DISCORD_WEBHOOKURL=${DISCORD_WEBHOOK_URL} - DIUN_NOTIF_WEBHOOK_ENDPOINT=${N8N_WEBHOOK_URL} - DIUN_NOTIF_WEBHOOK_HEADERS_AUTHORIZATION=Bearer ${DIUN_WEBHOOK_TOKEN} ``` ### Deux providers, deux logiques | Provider | Source | Comportement post-détection | |----------|--------|----------------------------| | **docker** | Containers en cours d'exécution | Auto-update si catégorie `critical` / `base` / approbation Telegram si `applicatif` | | **file** | `base-images.yml` (images FROM des Dockerfiles custom) | Notification + rebuild manuel ou approbation | Le fichier `base-images.yml` liste les images surveillées qui ne sont pas directement utilisées par un container : ```yaml - name: docker.n8n.io/n8nio/n8n:latest # base de n8n-custom - name: caddy:builder # base de caddy-crowdsec - name: caddy:latest - name: node:20-slim # base de cli-ollama - name: ghcr.io/astral-sh/uv:latest ``` ### Configuration ntfy ```yaml ntfy: image: binwiederhier/ntfy:latest command: serve volumes: - ntfy-cache:/var/cache/ntfy - ntfy-data:/var/lib/ntfy - ./ntfy/server.yml:/etc/ntfy/server.yml:ro ``` Le fichier `server.yml` impose `auth-default-access: deny-all` : chaque topic doit être publié par un utilisateur authentifié. Deux modes coexistent : | Mode | Cas d'usage | |------|-------------| | **Token Bearer** | Appels API depuis Alertmanager, N8N, scripts | | **User / password** | Authentification dans l'app mobile | ```bash # Gestion utilisateurs (depuis le VPS) docker exec ntfy ntfy user list docker exec -e NTFY_PASSWORD="..." ntfy ntfy user add --role=admin guillaume # Tokens d'API docker exec ntfy ntfy token add --label="alertmanager" alertmanager-bot docker exec ntfy ntfy token list ``` ### Topics utilisés | Topic | Producteurs | Consommateurs | |-------|-------------|---------------| | `alerts` | Alertmanager, Notification Hub (fallback) | Mobile, Telegram | | `updates` | Workflow Docker DIUN | Mobile | | `monitoring` | Grafana | Mobile | Publier un message : ```bash # Depuis l'extérieur (HTTPS via Caddy) curl -H "Authorization: Bearer tk_xxx" \ -H "Title: Disk Alert" \ -H "Priority: high" \ -H "Tags: warning" \ -d "Disk usage above 80%" \ https://ntfy.guigpap.com/alerts # Depuis l'intérieur (réseau Docker, depuis N8N) curl -H "Authorization: Bearer tk_xxx" \ -d "Message" \ http://ntfy:80/alerts ``` ### Intégration avec le workflow Docker DIUN DIUN n'applique aucune mise à jour : il poste un webhook authentifié vers N8N, qui prend toutes les décisions. ```mermaid flowchart TD D["DIUN scan · 0 */6 * * *"] Webhook["/webhook/notify/image-update · Bearer auth"] Switch["Switch Provider · docker / file"] Inspect["Docker Inspect"] Lookup["Lookup Policy · Data Table image_policies"] Cat{"Catégorie ?"} Critical["Critical · update immédiat"] Base["Base · queue 03h-05h"] Approval["Applicatif · approbation Telegram"] Exec["DIUN Update Executor · SW-1"] Hub["Notification Hub"] D --> Webhook --> Switch Switch -->|docker| Inspect --> Lookup --> Cat Switch -->|file| Hub Cat -->|critical| Critical --> Exec Cat -->|base| Base --> Exec Cat -->|applicatif| Approval --> Exec Exec --> Hub ``` La table `image_policies` (gérée dans N8N Data Tables) définit le comportement par image. Voir l'article workflow [Docker Updates](/fr/workflows/docker-updates/) pour le détail des sous-workflows et de la logique d'auto-rebuild. ### Commandes d'exploitation ```bash # Stack management docker compose -f notify-stack/docker-compose.yaml up -d docker compose -f notify-stack/docker-compose.yaml logs -f # DIUN — forcer un scan immédiat docker exec diun diun --run # DIUN — lister les images surveillées docker exec diun diun image list # ntfy — publier depuis le container (pour test) docker exec ntfy ntfy publish mytopic "Test message" ``` --- ## 4. Et si ? — Perspectives et limites ### Limites actuelles | Limite | Impact | Mitigation | |--------|--------|------------| | **DIUN ne pousse pas directement sur ntfy** | Toute notification mobile transite par N8N | Ajouter le notifier ntfy natif de DIUN à terme | | **Pas d'UI DIUN** | Visibilité uniquement via logs | Le workflow Docker DIUN sert de tableau de bord côté Telegram | | **ntfy single-node** | Pas de HA | Restart auto + monitoring du container | | **Quota Discord webhook** | Spam possible si beaucoup d'images bougent | DIUN groupe les notifs par scan | ### Scénarios d'évolution **Si le volume de notifications augmente** : - Configurer le notifier ntfy natif de DIUN (sortie directe, sans passer par N8N pour les notifs informatives). - Activer le bundling DIUN (regrouper plusieurs détections en une seule notification par scan). **Si je veux un fallback en cas de N8N indisponible** : - DIUN peut écrire en parallèle sur Discord (déjà fait) et ntfy (à ajouter), garantissant la trace même si le workflow N8N plante. **Si j'expose ntfy à d'autres utilisateurs** : - Créer des ACL par topic (lecture/écriture séparées). - Activer le rate limiting global dans `server.yml`. ### Métriques à surveiller | Métrique | Source | Seuil d'attention | |----------|--------|-------------------| | Détections DIUN par scan | `docker logs diun` | Spike inhabituel = changement de tag massif chez un éditeur | | Échecs webhook DIUN → N8N | logs DIUN + DLQ N8N | > 1 par scan = vérifier l'auth ou la disponibilité N8N | | Containers exclus | `docker exec diun diun image list` | Vérifier régulièrement que rien d'important n'est `diun.enable=false` par erreur | --- ## Pages liées ### Infrastructure - [Architecture VPS](/fr/infrastructure/architecture-vps/) — Vue d'ensemble - [Security Stack](/fr/infrastructure/security-stack/) — Caddy route `ntfy.guigpap.com` - [Monitoring Stack](/fr/infrastructure/monitoring-stack/) — Alertmanager → ntfy ### Workflows - [Docker Updates](/fr/workflows/docker-updates/) — Logique d'auto-update et d'approbation - [Notification Hub](/fr/workflows/notification-hub/) — Routage centralisé des notifications ### Référence - [Glossaire](/fr/reference/glossary/) — Webhook, Bearer token ## 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