[{"data":1,"prerenderedAt":188},["ShallowReactive",2],{"seo-verification":3,"blog-self-host-ntfy-vps-ma-fr":6,"promo-bar-likely":187},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-self-host-ntfy-vps-ma-fr",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":33,"intro":36,"sections":37,"ctaTitle":124,"ctaBody":125,"ctaButton":126,"ctaUrl":127,"relatedPosts":128},194,"self-host-ntfy-vps",{"fr":10,"en":12,"ar":13,"es":14},"self-host-ntfy-on-a-vps-push-notifications-for-scripts-and-cicd","استضافة-ntfy-على-vps-إشعارات-فورية-من-سكريبتاتك-وcicd","autoalojar-ntfy-en-un-vps","Héberger ntfy sur un VPS : notifications push pour vos scripts","Déployez ntfy sur votre VPS et envoyez des notifications push depuis n'importe quel script, cron ou pipeline CI\u002FCD avec un simple curl — sans SaaS ni clé d'API.",16,2,false,"2026-07-28T00:00:00+00:00","2026-11-04T16:30:26+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},8,"Sécurité & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-ntfy-vps-poster.svg",{"categorySlug":34,"appSlug":35},"monitoring","ntfy","Slack coûte par siège. Les e-mails sont noyés dans le bruit. Les webhooks Discord disparaissent dans un fil. ntfy (Apache 2.0, ~32 k ⭐, v2.30.0 — oct. 2026) résout le problème autrement : un serveur pub\u002Fsub HTTP que vous auto-hébergez sur votre VPS, et auquel n'importe quel script envoie une alerte avec un simple `curl -d`. L'application mobile reçoit le push en temps réel — même hors réseau local. Un seul conteneur Docker, \u003C 30 Mo RAM, aucun compte tiers requis. Dans cet article : déploiement, authentification, configuration multi-tenant avec `server.yml`, intégrations Backrest \u002F Uptime Kuma \u002F cron, notifications SMTP, et les cinq erreurs réelles que tout admin croise en production.",[38,42,55,58,86,89,92,96,99,102,112,115,118,121],{"type":39,"title":40,"body":41},"h2","Le problème : trop d'outils de monitoring, trop de canaux de notification","Uptime Kuma surveille vos services, Beszel surveille vos métriques VPS, Backrest gère vos sauvegardes, et vos cron jobs se taisent la nuit — sauf quand ils échouent. Chacun a son canal de notification : Slack, e-mail, webhook, Telegram. Résultat : cinq intégrations différentes à maintenir, cinq formats d'alertes à lire, et aucune vue unifiée quand quelque chose casse à 03h00. ntfy résout ce problème à l'envers : c'est vous qui hébergez le hub de notifications, et chaque outil ou script y envoie ses alertes en HTTP brut. Un seul topic à écouter sur votre téléphone, zéro dépendance à un service tiers.",{"type":43,"title":44,"items":45},"ul","Ce que ntfy apporte hors de la boîte",[46,47,48,49,50,51,52,53,54],"Envoi d'une notification avec un simple curl — `curl -d \"Build échoué\" https:\u002F\u002Fntfy.exemple.com\u002Falertes-ci` — zéro SDK, zéro bibliothèque.","Réception sur Android (F-Droid \u002F Play Store), iOS (App Store), navigateur desktop et interface web ntfy — tous souscrivent au même topic via WebSocket ou SSE.","Actions dans la notification — boutons qui déclenchent des callbacks HTTP, ouvrent des URLs ou exécutent des commandes sur l'appareil.","Notifications planifiées — livraison différée (`X-Delay: 30min`) pour programmer des rappels depuis des scripts.","Niveaux de priorité (min \u002F basse \u002F défaut \u002F haute \u002F urgente) avec contournement du mode Ne Pas Déranger pour les alertes critiques.","Pièces jointes — images ou fichiers jusqu'à 15 Mo via l'en-tête `X-Attach` ou un upload multipart.","Notifications SMTP — ntfy peut envoyer un e-mail de secours si votre appareil mobile est hors ligne ou si vous n'avez pas l'app installée.","Contrôle d'accès granulaire — utilisateurs, mots de passe hachés, tokens d'accès et ACL par topic via `ntfy user` et `ntfy access`.","\u003C 30 Mo RAM, SQLite (ou PostgreSQL pour les déploiements à haut débit), conteneur unique — le serveur de notifications push le plus léger de sa catégorie.",{"type":39,"title":56,"body":57},"Architecture : un pub\u002Fsub HTTP en conteneur unique","ntfy est un binaire Go qui tient en un seul conteneur Docker. Il expose une interface HTTP simple : `PUT` ou `POST` sur `\u002Fvotre-topic` publie un message ; n'importe quel client qui écoute ce topic (via WebSocket, SSE ou l'app mobile) le reçoit instantanément. Les messages sont mis en cache dans SQLite (`\u002Fvar\u002Flib\u002Fntfy\u002Fcache.db`) avec une rétention configurable (12 heures par défaut). Pour la production, ntfy s'attend à être placé derrière un reverse proxy nginx qui gère le TLS — le paramètre `behind-proxy: true` dans `server.yml` indique à ntfy de lire l'IP réelle depuis `X-Forwarded-For`. L'ensemble de la configuration avancée — authentification, SMTP, access control — vit dans un seul fichier `\u002Fetc\u002Fntfy\u002Fserver.yml` monté en volume Docker.",{"type":59,"title":60,"steps":61},"steps","Déployer ntfy en production : 8 étapes",[62,65,68,71,74,77,80,83],{"title":63,"body":64},"Déployer ntfy depuis le marketplace ServOrbit","Ouvrez votre tableau de bord ServOrbit → Marketplace → Monitoring → ntfy → Déployer. Docker tire `binwiederhier\u002Fntfy:v2.30.0`, démarre ntfy sur le port 8080 et l'interface web est accessible en moins de 5 secondes. Un reverse proxy nginx avec certificat Let's Encrypt est configuré automatiquement sur le domaine de votre choix.",{"title":66,"body":67},"Envoyer votre première notification","Depuis n'importe quel terminal avec curl :\n`curl -d \"Bonjour depuis mon VPS\" https:\u002F\u002Fntfy.exemple.com\u002Fmon-topic`\nOuvrez l'interface web ntfy sur la même URL, naviguez vers `mon-topic` et votre message s'affiche en temps réel. Les topics sont créés au premier envoi — aucun paramétrage préalable.",{"title":69,"body":70},"Créer le fichier server.yml complet","Montez un fichier de configuration dans le conteneur. Voici un `server.yml` de production :\n`base-url: https:\u002F\u002Fntfy.exemple.com`\n`listen-http: \":8080\"`\n`behind-proxy: true`\n# Cache SQLite (12h)\n`cache-file: \u002Fvar\u002Flib\u002Fntfy\u002Fcache.db`\n`cache-duration: 12h`\n# Authentification : personne ne peut lire ni écrire sans compte\n`auth-file: \u002Fvar\u002Flib\u002Fntfy\u002Fuser.db`\n`auth-default-access: deny-all`\n# SMTP sortant — ntfy envoie des e-mails de secours\n`smtp-sender-addr: smtp.exemple.com:587`\n`smtp-sender-user: notifications@exemple.com`\n`smtp-sender-pass: motdepasseSMTP`\n`smtp-sender-from: notifications@exemple.com`\nRedémarrez le conteneur après toute modification de ce fichier : `docker restart ntfy`.\nPour que les notifications arrivent aussi sur iOS, ajoutez `upstream-base-url: \"https:\u002F\u002Fntfy.sh\"` à ce fichier : la section « iOS » plus bas explique pourquoi.",{"title":72,"body":73},"Créer des utilisateurs et leurs tokens d'accès","Les tokens d'accès permettent à vos scripts d'envoyer des notifications sans exposer le mot de passe :\n# Créer un utilisateur admin interactif\n`docker exec -it ntfy ntfy user add --role=admin admin`\n# Créer un utilisateur dédié aux scripts (rôle user)\n`docker exec -it ntfy ntfy user add scripts`\n# Générer un token d'accès pour cet utilisateur\n`docker exec -it ntfy ntfy token add scripts`\n# Sortie : tk_AbCdEf123456...\n# Autoriser cet utilisateur à publier sur un topic spécifique\n`docker exec -it ntfy ntfy access scripts server-alerts rw`\nLe token `tk_AbCdEf123456` est utilisé à la place du mot de passe dans tous vos scripts.",{"title":75,"body":76},"Souscrire sur votre téléphone avec authentification","Installez l'app ntfy (Android : F-Droid ou Play Store ; iOS : App Store). Appuyez sur + → entrez l'URL de votre serveur → le topic. Quand ntfy demande des identifiants, entrez le nom d'utilisateur et le mot de passe du compte admin (ou un compte dédié lecture seule). Vous recevrez des notifications push dès qu'un message sera publié — via UnifiedPush (Android F-Droid), FCM (Android Play) ou APNs (iOS). Sur iOS, le push instantané n'arrive que si votre serveur a `upstream-base-url` défini (voir la section dédiée plus bas).",{"title":78,"body":79},"Alerter depuis vos cron jobs avec token","Utilisez le token d'accès dans l'en-tête `Authorization` :\n#!\u002Fbin\u002Fbash\n`NTFY_URL=\"https:\u002F\u002Fntfy.exemple.com\"`\n`NTFY_TOKEN=\"tk_AbCdEf123456\"`\n# Exécuter le backup\n`\u002Fusr\u002Flocal\u002Fbin\u002Fbackup.sh`\n`STATUS=$?`\n`if [ $STATUS -eq 0 ]; then`\n`curl -s -H \"Authorization: Bearer $NTFY_TOKEN\"        -H \"Title: Backup nuit\"        -H \"Priority: default\"        -H \"Tags: white_check_mark\"        -d \"Backup terminé à $(date)\"        \"$NTFY_URL\u002Fcron-jobs\"`\n`else`\n`curl -s -H \"Authorization: Bearer $NTFY_TOKEN\"        -H \"Title: Backup ÉCHOUÉ\"        -H \"Priority: urgent\"        -H \"Tags: warning\"        -d \"Backup échoué — code de sortie $STATUS\"        \"$NTFY_URL\u002Fcron-jobs\"`\n`fi`\nStockez le token dans `\u002Fetc\u002Fntfy-token` (chmod 600, propriétaire root) et non en dur dans le script.",{"title":81,"body":82},"Configurer Backrest et Uptime Kuma","**Backrest** (sauvegardes Restic via interface web) : dans l'interface Backrest → Plans → votre plan → Hooks → Add Hook → type `Webhook (ntfy)` → entrez l'URL `https:\u002F\u002Fntfy.exemple.com\u002Fbackups` et le token Bearer. Backrest notifie à chaque fin de sauvegarde, succès comme erreur, avec les statistiques de la snapshot.\n\n**Uptime Kuma** : Paramètres → Notifications → Nouveau → type `ntfy` → Server URL : `https:\u002F\u002Fntfy.exemple.com` → Topic : `server-alerts` → Username \u002F Password (ou laissez vide si vous utilisez un token dans un champ custom). Testez la notification depuis l'interface Uptime Kuma avant de valider.\n\n**Grafana** : Contact points → New → type `webhook` → URL `https:\u002F\u002Fntfy.exemple.com\u002Fgrafana` → HTTP headers : `Authorization: Bearer tk_AbCdEf123456` → `Content-Type: text\u002Fplain`.",{"title":84,"body":85},"Activer les notifications e-mail de secours (SMTP)","Une fois `smtp-sender-addr` configuré dans `server.yml`, envoyez une notification avec l'en-tête `X-Email` :\n`curl -H \"Authorization: Bearer $NTFY_TOKEN\"      -H \"Title: Alerte critique\"      -H \"X-Email: vous@exemple.com\"      -d \"Disque plein à 95%\"      https:\u002F\u002Fntfy.exemple.com\u002Fserver-alerts`\nntfy envoie la notification push ET un e-mail. Utile pour les alertes où l'app mobile n'est pas installée ou pour archiver les incidents dans votre boîte mail.",{"type":39,"title":87,"body":88},"Authentification et tokens d'accès : ne jamais exposer un topic public","Par défaut, ntfy démarre sans contrôle d'accès : la doc indique que `auth-default-access` vaut `read-write`, donc **n'importe qui connaissant l'URL peut lire et écrire**. En production, trois niveaux de protection s'empilent : d'abord `auth-default-access: deny-all` qui ferme le serveur à tout inconnu ; ensuite des utilisateurs créés via `ntfy user add` avec des mots de passe hachés stockés dans `user.db` (bcrypt, jamais en clair) ; enfin des tokens d'accès (`ntfy token add`) liés à un utilisateur spécifique, révocables indépendamment du mot de passe. Un token compromis se révoque sans changer le mot de passe de l'utilisateur. Les ACL par topic (`ntfy access`) permettent de cloisonner : l'utilisateur `backrest` ne peut écrire que sur `backups`, il ne voit pas `server-alerts`.",{"type":39,"title":90,"body":91},"Configuration multi-tenant : un serveur, plusieurs équipes","ntfy supporte plusieurs « espaces » sur le même serveur via les namespaces de topics. Créez un utilisateur par service ou par équipe, accordez-lui les droits uniquement sur ses topics, et chaque service croit avoir son propre hub. Exemple : l'utilisateur `ci-bot` a le droit `rw` sur `ci-builds` et `ci-deploys` ; l'utilisateur `ops-bot` a le droit `rw` sur `server-alerts` et `cron-jobs`. L'admin (rôle `admin`) voit tout. La séparation est purement logique — un seul processus ntfy, une seule base SQLite, une seule URL de base. Pour des équipes vraiment séparées qui ne doivent pas partager l'instance, déployez deux conteneurs ntfy sur deux sous-domaines distincts.",{"type":93,"title":94,"body":95},"tip","Tip : noms de topics comme namespaces et stratégie de silence nocturne","Organisez vos alertes par source : `ci-builds` pour GitHub Actions\u002FGitLab CI, `server-alerts` pour Uptime Kuma\u002FBeszel, `cron-jobs` pour vos scripts batch, `backups` pour Backrest. L'app ntfy vous permet de mettre en sourdine certains topics la nuit (ex. `cron-jobs`) tout en gardant `server-alerts` en alerte maximale avec contournement du mode Ne Pas Déranger. Aucune configuration côté serveur — juste le nom du topic dans le curl et les préférences de l'app mobile.",{"type":39,"title":97,"body":98},"Dépannage : 5 erreurs réelles en production","**1. `HTTP 403 Forbidden` à l'envoi ou à la lecture**\nMessage : `{\"code\":40301,\"http\":403,\"error\":\"Unauthorized\"}`\nCause : `auth-default-access: deny-all` est actif et le token manque ou est expiré. Vérifiez l'en-tête : `curl -v -H \"Authorization: Bearer tk_...\" https:\u002F\u002Fntfy.exemple.com\u002Fmon-topic`. Si le token est absent du header, le serveur rejette silencieusement. Régénérez le token avec `ntfy token add \u003Cutilisateur>` et mettez à jour vos scripts.\n\n**2. Notification envoyée mais jamais reçue sur mobile**\nSur Android, vérifiez d'abord que l'app est abonnée à votre instance et non au serveur public `ntfy.sh` (URL dans les paramètres de l'app). Sur iOS, la cause la plus probable est l'absence de `upstream-base-url: \"https:\u002F\u002Fntfy.sh\"` dans `server.yml` : sans ce relais, la doc prévient que la livraison peut prendre des heures. Configurez-le, puis déroulez la checklist de la section iOS plus bas. `base-url` doit aussi être défini, mais la doc le relie aux URL de pièces jointes et au pied des e-mails, pas à l'arrivée du push.\n\n**3. Liens incorrects dans les e-mails sortants**\nLes e-mails SMTP envoyés par ntfy contiennent des liens vers les notifications. Sans `base-url` dans `server.yml`, le pied de l'e-mail (lien vers la notification) est construit sans l'URL publique et reste inutilisable depuis l'extérieur. Solution : définir `base-url: https:\u002F\u002Fntfy.exemple.com` et redémarrer le conteneur.\n\n**4. WebSocket drops répétés en production (reconnexions toutes les 30 s)**\nCause : le timeout keepalive de nginx est inférieur à l'intervalle de heartbeat de ntfy (`keepalive-interval: \"45s\"` dans la configuration d'exemple de la doc). Le proxy ferme la connexion WebSocket avant que ntfy ne puisse envoyer son heartbeat. Ajoutez dans le bloc `location` nginx : `proxy_read_timeout 60;` et `proxy_send_timeout 60;`. Vérifiez aussi que `proxy_http_version 1.1;` et `proxy_set_header Upgrade $http_upgrade;` sont présents — sans eux, WebSocket est dégradé en long-polling SSE.\n\n**5. OOM (Out of Memory) sur un topic à très haut débit**\nntfy garde les messages récents en mémoire avant de les écrire dans SQLite. Sur un topic qui reçoit des centaines de messages par seconde (ex. logs en temps réel mal filtrés), le buffer mémoire peut saturer un VPS à 512 Mo. Solution immédiate : réduire `cache-duration` à `1h` ou `30m` pour ce serveur. Solution structurelle : ne jamais utiliser ntfy comme système de log en temps réel — utilisez un filtre côté script (`| grep -E 'ERROR|WARN'`) pour ne pousser que les événements pertinents. Pour les déploiements à très haut débit, ntfy peut utiliser PostgreSQL à la place de SQLite pour ses stockages (voir la doc de configuration).",{"type":39,"title":100,"body":101},"iOS : pourquoi un ntfy auto-hébergé passe par ntfy.sh pour le push","Sur iOS, une app ne peut pas garder une connexion ouverte en arrière-plan : la documentation ntfy explique que cette restriction rend impossible un push instantané sans serveur central. Votre serveur auto-hébergé transmet donc, pour chaque message, une requête de « poll » à un serveur amont, `ntfy.sh` par défaut, qui se charge de réveiller l'app. Le réglage s'appelle `upstream-base-url: \"https:\u002F\u002Fntfy.sh\"`. Cette requête ne contient que l'identifiant du message (en-tête `X-Poll-ID`) et l'empreinte SHA-256 de l'URL du topic, jamais le texte : le serveur auto-hébergé envoie littéralement « New message », et l'app va chercher le vrai contenu chez vous. Sans `upstream-base-url`, la documentation prévient que les notifications finissent par arriver, mais que la livraison peut prendre des heures (20 à 30 minutes si le téléphone est activement utilisé). Le paramètre `upstream-access-token` est facultatif : la doc ne le réserve qu'au cas où les limites du serveur amont sont dépassées ou si celui-ci est protégé.",{"type":43,"title":103,"items":104},"Checklist iOS : sept vérifications avant de chercher plus loin",[105,106,107,108,109,110,111],"**`base-url`** — défini sur l'URL publique en HTTPS de votre serveur, celle que le téléphone peut joindre.","**`upstream-base-url`** — présent dans `server.yml` (ou en variable d'environnement), valeur `https:\u002F\u002Fntfy.sh`, conteneur redémarré.","**Serveur par défaut de l'app** — dans les réglages de l'app iOS, l'URL de votre serveur est celle qui est déclarée comme serveur par défaut.","**Abonnement au bon serveur** — le topic a été ajouté en choisissant votre serveur, pas `ntfy.sh` : un topic du même nom sur le serveur public est un autre topic.","**Jeton amont** — `upstream-access-token` ne sert que si les limites du relais sont atteintes ; sans cause établie, ne l'ajoutez pas par réflexe en espérant régler le problème.","**Journaux du serveur** — vérifiez que le message est bien publié puis transmis au relais. Si c'est le cas, votre côté fonctionne et le problème se situe entre le relais, Apple et le téléphone.","**Réglages du téléphone** — Actualisation en arrière-plan et Notifications activées pour l'app, et aucun bloqueur DNS (AdGuard Home, Pi-hole) qui filtre `ntfy.sh`.",{"type":39,"title":113,"body":114},"Quand rien n'arrive malgré tout : ce que disent vraiment les issues #1305 et #1844","Ces deux issues du dépôt ntfy décrivent le symptôme que vous cherchez : un serveur auto-hébergé, un push iOS qui ne s'affiche pas, des messages qui n'apparaissent qu'en rafraîchissant l'app à la main. Lues le 30 octobre 2026, elles sont toutes deux ouvertes et aucune ne désigne une cause confirmée.\n\n**#1305 « No push notifications on ios? »** (ouverte en mars 2025, étiquettes ios et bug). Le rapporteur n'obtient aucune bannière, ni avec ntfy.sh ni avec sa propre instance. Des commentaires disent qu'une réinstallation de l'app a aidé, d'autres que le problème est revenu des mois plus tard. Un contributeur propose que l'app se réabonne aux topics Firebase au lancement et a ouvert une PR brouillon, en précisant qu'il n'a pas pu la tester. Un mainteneur demande au rapporteur si l'abonnement Firebase est en cause, sans conclure.\n\n**#1844 « No iOS Push notification, also with valid subscription »** (ouverte en juillet 2026, étiquettes ios, server et bug). Le rapporteur fait tourner ntfy dans Docker avec `NTFY_UPSTREAM_BASE_URL` sur `https:\u002F\u002Fntfy.sh` et `NTFY_UPSTREAM_ACCESS_TOKEN` renseigné. Il dit avoir atteint la limite gratuite de 250 messages par jour, puis pris un abonnement payant. Ses journaux montrent le message publié et envoyé au relais, et pourtant aucun push. Un contributeur répond que des erreurs 429 peuvent valoir un bannissement d'IP pouvant durer jusqu'à 4 heures, constate que le test `curl` du rapporteur passe (donc pas de bannissement), et que le compte affichait 48 messages envoyés sur 2 500. Il ajoute que les notifications iOS sont capricieuses sans que l'on sache exactement pourquoi. Contournement rapporté : désactiver puis réactiver « Actualisation en arrière-plan » et « Notifications » dans les réglages iOS. L'auteur écrit ne pas savoir pourquoi cela marche ; le problème est revenu, puis reparti sans cause connue, et un autre utilisateur confirme le contournement en septembre 2026. Un autre rapport relie un cas voisin à des listes de blocage DNS.\n\n**Ce qu'on peut en conclure, et ce qu'on ne peut pas.** Ni une limite de messages par jour ni un blocage 429 ne sont établis comme cause dans ces fils : le 429 n'y est écarté pour l'IP du rapporteur, et la limite de 250 messages est un chiffre donné par lui, pas par la documentation de configuration. Le jeton amont n'y règle pas le problème. Traitez donc la liste ci-dessus comme des vérifications, pas comme un correctif garanti.",{"type":93,"title":116,"body":117},"Tip : ne confiez pas une alerte critique au seul push iOS","Tant que ces issues restent ouvertes, doublez les alertes qui comptent : ajoutez l'en-tête `X-Email` (voir l'étape SMTP) pour recevoir aussi un e-mail, ou gardez un second canal sur le téléphone. Les contributeurs des deux issues suggèrent par ailleurs la PWA (web push) comme alternative à l'app iOS. Et testez de bout en bout après chaque mise à jour de l'app ou d'iOS, avec le heartbeat du watchdog décrit plus haut.",{"type":39,"title":119,"body":120},"Intégrations avancées : Backrest, Uptime Kuma, Grafana","**Backrest** est le gestionnaire d'interface web pour les sauvegardes Restic. Il supporte nativement ntfy comme type de hook : configurez l'URL du topic et le token Bearer dans l'interface Backrest, et chaque snapshot réussie ou échouée génère automatiquement une notification push avec le nom de la snapshot, la taille dédupliquée et la durée. C'est le cas d'usage le plus propre : zero script, zero cron, l'intégration est dans l'outil lui-même.\n\n**Uptime Kuma** supporte ntfy nativement dans son gestionnaire de notifications. La configuration prend moins d'une minute : nom d'utilisateur + mot de passe (ou laissez vide et ajoutez `Authorization: Bearer` dans les headers personnalisés). Chaque monitor (HTTP, port TCP, ping, certificat TLS) peut avoir plusieurs canaux de notification — combinez ntfy pour le push mobile et l'e-mail SMTP de ntfy pour la traçabilité.\n\n**Grafana** utilise les webhooks génériques. Créez un contact point de type `webhook`, pointez sur `https:\u002F\u002Fntfy.exemple.com\u002Fgrafana`, ajoutez l'en-tête `Authorization: Bearer tk_...` et `Content-Type: text\u002Fplain`. Les alertes Grafana (CPU > 90%, latence P99, disk > 80%) arrivent immédiatement sur votre téléphone avec le nom de la règle dans le titre.",{"type":93,"title":122,"body":123},"Tip : tester la livraison de bout en bout avant de compter dessus","Avant de brancher votre infrastructure sur ntfy, testez la chaîne complète : envoyez une notification avec `curl`, vérifiez qu'elle apparaît dans l'interface web, qu'elle arrive sur l'app mobile, et que l'e-mail SMTP de secours atterrit dans la boîte mail. Un ntfy qui ne livre pas silencieusement est pire qu'une absence de monitoring — vous croyez être notifié, mais vous ne l'êtes pas. Planifiez un cron `*\u002F30 * * * *` qui envoie un heartbeat sur un topic `watchdog` — si l'app mobile ne reçoit pas ce heartbeat en 30 minutes, c'est ntfy lui-même qui est down.","Votre hub de notifications sous votre contrôle","Déployez ntfy sur un VPS ServOrbit et centralisez toutes vos alertes monitoring, CI\u002FCD et cron en un hub de notifications self-hosted — sans SaaS, sans abonnement.","Déployer ntfy","\u002Fapplications\u002Fmonitoring\u002Fntfy",[129,146,169],{"id":130,"slug":131,"slugs":132,"title":136,"excerpt":137,"readTime":23,"views":18,"isPinned":19,"noindex":19,"publishedAt":138,"updatedAt":139,"category":140,"categories":141,"featuredImage":30,"bgImage":31,"posterImage":143,"relatedSolution":144},133,"self-host-beszel-vps",{"fr":131,"en":133,"ar":134,"es":135},"self-host-beszel-multi-server-monitoring-hub-on-your-vps","استضف-beszel-على-vps-مركز-مراقبة-متعدد-الخوادم","alojar-beszel-hub-monitorizacion-vps","Beszel sur VPS : supervision multi-serveurs, alertes et sécurité","Supervisez un parc de VPS depuis un hub Beszel unique : alertes Telegram\u002Fe-mail, 2FA, agents déclarés automatiquement et dépannage des connexions silencieuses.","2026-02-14T00:00:00+00:00","2026-11-04T16:30:25+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[142],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fself-host-beszel-vps-poster.svg",{"categorySlug":34,"appSlug":145},"beszel",{"id":147,"slug":148,"slugs":149,"title":153,"excerpt":154,"readTime":155,"views":18,"isPinned":19,"noindex":19,"publishedAt":156,"updatedAt":157,"category":158,"categories":164,"featuredImage":30,"bgImage":31,"posterImage":166,"relatedSolution":167},167,"self-host-dozzle-vps",{"fr":148,"en":150,"ar":151,"es":152},"how-to-self-host-dozzle-on-a-vps-real-time-docker-log-viewer","استضافة-dozzle-على-vps-عارض-سجلات-docker-لحظيا","alojar-dozzle-en-un-vps","Héberger Dozzle sur un VPS : logs Docker en temps réel","Déployez Dozzle sur votre VPS : un visualiseur de logs Docker open source et sans état. Suivez et recherchez en direct les logs de vos conteneurs, sans SSH.",4,"2026-07-06T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":159,"name":160,"slug":161,"color":162,"icon":163},7,"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[165],{"id":159,"name":160,"slug":161,"color":162,"icon":163},"\u002Fblog\u002Fcovers\u002Fself-host-dozzle-vps-poster.svg",{"categorySlug":34,"appSlug":168},"dozzle",{"id":170,"slug":171,"slugs":172,"title":176,"excerpt":177,"readTime":178,"views":179,"isPinned":19,"noindex":19,"publishedAt":180,"updatedAt":157,"category":181,"categories":182,"featuredImage":30,"bgImage":31,"posterImage":184,"relatedSolution":185},182,"self-host-changedetection-vps",{"fr":171,"en":173,"ar":174,"es":175},"self-host-changedetectionio-on-a-vps-monitor-any-website","استضافة-changedetectionio-على-vps-مراقبة-تغييرات-المواقع","alojar-changedetection-io-en-un-vps","Héberger Changedetection.io sur un VPS : veille de sites web","Changedetection.io sur VPS : détection open source des changements de sites, filtres CSS\u002FXPath, 80+ canaux. Régressions v0.60.x documentées.",9,0,"2026-07-17T00:00:00+00:00",{"id":159,"name":160,"slug":161,"color":162,"icon":163},[183],{"id":159,"name":160,"slug":161,"color":162,"icon":163},"\u002Fblog\u002Fcovers\u002Fself-host-changedetection-vps-poster.svg",{"categorySlug":34,"appSlug":186},"changedetection",true,1794270795917]