Push-Benachrichtigungen selbst hosten mit ntfy
ntfy mit Docker und Caddy selbst hosten, absichern und Meldungen von Skripten, Uptime Kuma und Home Assistant aufs iPhone und Android-Handy schicken.
Von Nathan Base
Früher oder später will jeder Selfhoster vom eigenen Server benachrichtigt werden: wenn das Backup fehlschlägt, eine Website nicht mehr antwortet oder die Waschmaschine fertig ist. Die üblichen Wege haben alle einen Haken. Telegram-Bots laufen über die Server eines Messengers, E-Mails gehen in der Flut unter, und die Push-Funktion der Home-Assistant-App hilft nur bei Meldungen aus Home Assistant.
ntfy ist ein schlanker Dienst, der genau eine Sache gut macht: Er nimmt eine Nachricht per einfachem HTTP-Aufruf entgegen und schickt sie als Push-Benachrichtigung an Dein Handy. Ein Skript braucht dafür nur eine Zeile curl. Es gibt Apps für Android und iOS, und Uptime Kuma und Home Assistant können ntfy direkt ansprechen.
Den öffentlichen Dienst ntfy.sh kannst Du sofort nutzen, aber jeder, der Deinen Kanalnamen errät, liest mit. Diese Anleitung zeigt deshalb, wie Du ntfy selbst hostest, mit Benutzern absicherst und Deine Dienste anbindest. Stand ist ntfy 2.37 vom November 2026. Grundlage ist die offizielle ntfy-Dokumentation.
Was Du brauchst
- Einen Linux-Server mit Docker, der aus dem Internet erreichbar ist. Ein kleines Droplet bei DigitalOcean mit 1 GB RAM reicht völlig aus. Wenn Du noch kein Konto hast, bekommst Du über diesen Link zu DigitalOcean (Affiliate Link) Startguthaben zum Ausprobieren.
- Eine Subdomain wie
ntfy.example.com, deren DNS-Eintrag auf die IP-Adresse des Servers zeigt. - Die Ports 80 und 443 müssen in der Firewall offen sein, damit Caddy ein HTTPS-Zertifikat holen kann.
Läuft auf Deinem Server bereits Coolify oder ein anderer Reverse Proxy, lässt Du den Caddy-Teil weg und trägst die Domain stattdessen dort ein.
ntfy mit Docker Compose starten
Lege einen Ordner für ntfy an und wechsle hinein:
mkdir -p ~/ntfy
cd ~/ntfyErstelle darin die Datei compose.yml mit nano compose.yml und diesem Inhalt:
services:
ntfy:
image: binwiederhier/ntfy
command: serve
restart: unless-stopped
environment:
NTFY_BASE_URL: https://ntfy.example.com
NTFY_CACHE_FILE: /var/lib/ntfy/cache.db
NTFY_AUTH_FILE: /var/lib/ntfy/auth.db
NTFY_AUTH_DEFAULT_ACCESS: deny-all
NTFY_BEHIND_PROXY: "true"
NTFY_ENABLE_LOGIN: "true"
NTFY_UPSTREAM_BASE_URL: https://ntfy.sh
volumes:
- ./data:/var/lib/ntfy
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./caddy-data:/dataDie wichtigsten Zeilen im Überblick:
NTFY_BASE_URList die Adresse, unter der Dein Server erreichbar ist. Ersetzentfy.example.comdurch Deine Subdomain.NTFY_AUTH_FILEschaltet die Benutzerverwaltung ein, undNTFY_AUTH_DEFAULT_ACCESS: deny-allsorgt dafür, dass ohne Anmeldung niemand lesen oder senden darf. Ohne diese Zeile wäre jeder Kanal offen.NTFY_CACHE_FILEspeichert Nachrichten eine Weile zwischen, damit ein Handy, das kurz offline war, sie nachträglich abholt.NTFY_UPSTREAM_BASE_URList für iPhones nötig. Apple erlaubt Apps keine dauerhafte Verbindung im Hintergrund, deshalb schickt Dein Server bei jeder Nachricht einen inhaltslosen Weckruf über ntfy.sh. Die iOS-App holt den eigentlichen Text dann direkt von Deinem Server. Ohne diese Zeile kommen Nachrichten auf dem iPhone teils mit großer Verzögerung an.
Lege dann die Datei Caddyfile mit nano Caddyfile an:
ntfy.example.com {
reverse_proxy ntfy:80
}Caddy holt für die Domain automatisch ein Zertifikat von Let’s Encrypt und leitet alle Anfragen an den ntfy-Container weiter. Starte beide Container:
docker compose up -dÖffne nach etwa einer Minute https://ntfy.example.com im Browser. Du siehst die Weboberfläche von ntfy mit einem Anmeldeknopf.
Benutzer und Zugangstoken anlegen
Lege zuerst einen Administrator an. Der Befehl fragt zweimal nach einem Passwort:
docker compose exec ntfy ntfy user add --role=admin nathanErsetze nathan durch Deinen Benutzernamen. Ein Administrator darf alle Kanäle lesen und beschreiben, damit meldest Du Dich in den Apps an.
Skripte sollen sich nicht mit Deinem Passwort anmelden. Dafür gibt es Zugangstoken, die Du jederzeit einzeln widerrufen kannst:
docker compose exec ntfy ntfy token add --label=server nathanntfy gibt einen Token aus, der mit tk_ beginnt. Kopiere ihn, er erscheint später nur noch gekürzt in der Liste. Für Dienste wie Home Assistant kannst Du zusätzlich eigene Benutzer anlegen, die nur auf bestimmte Kanäle zugreifen dürfen:
docker compose exec ntfy ntfy user add homeassistant
docker compose exec ntfy ntfy access homeassistant 'haus' read-writeDie Apps einrichten
Installiere die ntfy-App aus dem App Store oder aus Google Play. In der iOS-App tippst Du auf Settings, fügst unter Users Deinen Server mit Benutzername und Passwort hinzu und legst danach mit dem Plus-Symbol ein Abo an. Gib als Kanal zum Beispiel server ein, aktiviere Use another server und trage https://ntfy.example.com ein. In der Android-App funktioniert es genauso. Dort kannst Du Deinen Server zusätzlich in den Einstellungen als Standard festlegen.
Ein Kanal heißt bei ntfy Topic und entsteht in dem Moment, in dem Du ihn abonnierst oder die erste Nachricht hineinschickst. Sinnvoll ist eine Aufteilung nach Herkunft, etwa server für Backups und Systemmeldungen, monitoring für Uptime Kuma und haus für Home Assistant. In der App kannst Du dann je Kanal festlegen, wie laut er sich melden darf.
Die erste Nachricht senden
Probiere es direkt im Terminal aus. Ersetze den Token durch Deinen:
curl -H "Authorization: Bearer tk_DEIN_TOKEN" -H "Title: Test" -d "Hallo vom Server" https://ntfy.example.com/serverNach ein, zwei Sekunden muss die Nachricht auf dem Handy erscheinen. Mit weiteren Kopfzeilen steuerst Du das Aussehen: -H "Priority: high" lässt das Handy auch bei leisem Kanal deutlich klingeln, und -H "Tags: warning" setzt ein Warnsymbol vor den Titel.
Skripte, Uptime Kuma und Home Assistant anbinden
Shell-Skripte. Am nützlichsten ist eine Meldung, wenn ein Skript fehlschlägt. In einem Bash-Skript mit set -e reicht dafür eine Zeile am Anfang, die bei jedem Fehler feuert:
trap 'curl -s -H "Authorization: Bearer tk_DEIN_TOKEN" -H "Priority: high" -H "Title: Backup fehlgeschlagen" -d "Das Backup auf $(hostname) ist fehlgeschlagen" https://ntfy.example.com/server' ERRGenau so lässt sich das Backup-Skript aus der Anleitung Backups mit restic: verschlüsselt auf S3 und Spaces ergänzen, damit Du von einem fehlgeschlagenen Backup sofort erfährst.
Uptime Kuma. Öffne in Uptime Kuma Einstellungen > Benachrichtigungen > Benachrichtigung einrichten und wähle als Typ Ntfy. Trage die Server-Adresse und den Kanal monitoring ein, wähle als Anmeldung den Zugangstoken und füge ihn ein. Über Testen prüfst Du, ob die Nachricht ankommt. Wenn Du Uptime Kuma auch nutzt, um Geräte per Heartbeat zu überwachen, wie in Android-Handy per Heartbeat in Uptime Kuma überwachen beschrieben, landen die Ausfälle damit ebenfalls bei ntfy.
Home Assistant. Seit 2025 gibt es eine eingebaute ntfy-Integration. Füge sie unter Einstellungen > Geräte & Dienste > Integration hinzufügen hinzu, trage Deine Server-Adresse sowie den Benutzer homeassistant mit Passwort ein und lege danach über Topic hinzufügen den Kanal haus an. Home Assistant erzeugt daraus eine Benachrichtigungs-Entität. In einer Automation verwendest Du sie so:
action: notify.send_message
target:
entity_id: notify.ntfy_haus
data:
title: Waschmaschine
message: Die Wäsche ist fertig.Den genauen Namen der Entität findest Du unter Einstellungen > Geräte & Dienste > ntfy.
Typische Fehler und ihre Lösung
Die Weboberfläche ist nicht erreichbar. Prüfe mit docker compose logs caddy, ob Caddy ein Zertifikat bekommen hat. Meist zeigt der DNS-Eintrag noch nicht auf den Server, oder Port 80 ist in der Firewall gesperrt.
curl meldet forbidden. Der Token gehört zu einem Benutzer ohne Schreibrecht auf diesen Kanal, oder er ist falsch kopiert. Mit docker compose exec ntfy ntfy token list siehst Du alle Token, mit docker compose exec ntfy ntfy access alle Rechte.
Auf dem iPhone kommen Nachrichten erst Minuten später an. Prüfe, ob NTFY_UPSTREAM_BASE_URL gesetzt ist und ob Dein Server ntfy.sh erreichen kann. Und prüfe in den iOS-Einstellungen unter Mitteilungen > ntfy, ob Mitteilungen erlaubt sind.
Was Du davon hast
Mit zwei Containern und zehn Minuten Arbeit hast Du einen eigenen Push-Dienst, den jedes Skript, jeder Monitor und Home Assistant mit einer Zeile ansprechen können. Die Nachrichten bleiben auf Deinem Server, nur der inhaltslose Weckruf für iPhones geht über ntfy.sh. Am meisten lohnt es sich bei den Meldungen, die Du sonst nie bekommen würdest: dem Backup, das nachts still scheitert, und dem Dienst, der seit Stunden nicht mehr antwortet.
Weiterlesen.
-
Web & CodeAndroid-Handy per Heartbeat in Uptime Kuma überwachen
Fällt ein Android-Handy als SMS-Empfänger aus, meldet es ein Push-Monitor in Uptime Kuma. Vier Wege für den Heartbeat im Vergleich.
Nathan Base -
Web & CodeBackups mit restic: verschlüsselt auf S3 und Spaces
Server und Mac mit restic sichern: verschlüsselt, inkrementell und automatisch auf DigitalOcean Spaces oder anderen S3-Speicher, samt Restore.
Nathan Base -
Raspberry Pi & LinuxHome Assistant: Internet-Ausfall der FRITZ!Box melden
So meldet Home Assistant jeden DSL- oder Glasfaser-Ausfall Deiner FRITZ!Box aufs Handy, inklusive Dauer der Störung und Tipp für Pushs ohne Internet.
Nathan Base -
Web & CodeAuthentik einrichten: ein Login für alle eigenen Dienste
Single Sign-on für Selfhosting: Authentik mit Docker installieren, absichern und Immich per OpenID Connect anbinden, damit ein Konto für alles reicht.
Nathan Base -
Web & CodeDocker-Container aktualisieren: Diun statt Watchtower
Watchtower ist eingestellt. Mit Diun und ntfy erfährst Du von neuen Docker-Images und aktualisierst Container kontrolliert statt blind.
Nathan Base -
Web & CodeVaultwarden auf einem Droplet: eigener Passwortmanager
Eigener Passwortmanager mit Vaultwarden: Bitwarden-kompatiblen Server mit Docker Compose, Caddy und HTTPS auf einem Droplet einrichten.
Nathan Base