ntfy selbst hosten: Push-Alarme per Docker einrichten
Betreiben Sie ntfy auf einem VPS mit TLS und Docker Compose. Sichern Sie Topics per Benutzern und ACLs und senden Sie Alarme aus cron oder systemd OnFailure.
Was ein selbst gehosteter ntfy-Server leistet
Ein selbst gehosteter ntfy-Server wandelt eine HTTP-POST-Anfrage in eine Push-Benachrichtigung auf Ihrem Smartphone um. Sie veröffentlichen die Nachricht mit curl. Sie kommt in der Android-App, der iOS-App, einem Browser-Tab oder jedem anderen Client an, der eine HTTP-Verbindung offen halten kann. Sie müssen keine Client-Bibliothek installieren und keinen Message Broker betreiben.
ntfy adressiert Nachrichten über ein Topic. Ein Topic ist ein Name im URL-Pfad, beispielsweise https://ntfy.example.com/alerts. Es wird in dem Moment angelegt, in dem jemand eine Nachricht daran veröffentlicht. Bei einer Standardinstallation kann jeder, der diesen Namen kennt, das Topic lesen und Nachrichten daran veröffentlichen. Deshalb vergleicht die Dokumentation des Projekts den Topic-Namen mit einem Passwort. Dieses Modell eignet sich für den öffentlichen Dienst ntfy.sh. Für einen Server, der beispielsweise Fehler Ihrer Backups meldet, ist es nicht geeignet. Daher aktiviert diese Anleitung die Authentifizierung, bevor die erste Nachricht gesendet wird.
Was Sie benötigen
Sie benötigen einen VPS mit Ubuntu 24.04 oder Debian 13, Docker Engine und dem Compose-Plugin, einen Domainnamen sowie sehr wenig RAM. Legen Sie einen DNS-A-Record (Domain Name System) an, der ntfy.example.com auf die öffentliche IP-Adresse des Servers verweist. Prüfen Sie anschließend die Auflösung, bevor Sie weitere Schritte durchführen.
dig +short ntfy.example.com
sudo ufw allow 80,443/tcp
sudo ufw statusdig muss die IP-Adresse Ihres Servers ausgeben. Die Ausstellung des Zertifikats schlägt fehl, wenn keine Ausgabe erfolgt, weil die Zertifizierungsstelle den Namen von außen prüft. Port 80 bleibt geöffnet, da ACME (Automatic Certificate Management Environment), das Protokoll hinter Let's Encrypt, ihn für die HTTP-Challenge verwendet. Der ntfy-Container erhält selbst keinen öffentlichen Port.
ntfy-Konfigurationsdatei erstellen
Das Docker-Image enthält keine Konfigurationsdatei. Sie erstellen daher eine Datei. Jeder spätere Befehl in dieser Anleitung liest daraus. Ermitteln Sie zuerst die Benutzer-ID und die Gruppen-ID, unter denen der Container ausgeführt wird.
id -u
id -g
sudo install -d -o "$(id -u)" -g "$(id -g)" /etc/ntfy /var/cache/ntfy /var/lib/ntfy
sudo nano /etc/ntfy/server.ymlbase-url: "https://ntfy.example.com"
listen-http: ":2586"
behind-proxy: true
cache-file: "/var/cache/ntfy/cache.db"
cache-duration: "12h"
auth-file: "/var/lib/ntfy/user.db"
auth-default-access: "deny-all"
enable-login: true
enable-signup: falseVier dieser Zeilen sind entscheidend. base-url muss die exakte öffentliche HTTPS-Adresse sein, weil ntfy daraus Links zu Anhängen und die eigenen Anfragen der Webanwendung erstellt. Ein falscher Wert führt daher dazu, dass die Webanwendung geladen wird und anschließend jede Aktion fehlschlägt. listen-http: ":2586" bindet innerhalb des Containers an alle Schnittstellen. Das wirkt nachlässig, ist hier aber korrekt: Der Container hat einen eigenen Netzwerk-Namespace. Würde der Dienst dort an 127.0.0.1 gebunden, wäre der Port vom Host aus nicht erreichbar, und der von Docker veröffentlichte Port könnte keine Verbindung herstellen. auth-default-access: "deny-all" definiert die gesamte Sicherheitskonfiguration, weil Lese- und Schreibzugriffe ohne explizite Berechtigung verweigert werden. behind-proxy: true weist ntfy an, die Client-Adresse aus dem Header X-Forwarded-For zu übernehmen. Dadurch berücksichtigen Ratenlimits die tatsächlichen Besucher, statt den Reverse Proxy als einen einzigen, besonders aktiven Client zu zählen.
enable-login: true ermöglicht die Anmeldung der Webanwendung und der Smartphone-Apps mit einem Passwort. enable-signup bleibt auf false gesetzt, weil die selbstständige Kontoerstellung auf einem privaten Server eine zusätzliche Zugangsmöglichkeit ohne wirklichen Nutzen wäre.
sudo chown "$(id -u):$(id -g)" /etc/ntfy/server.yml
sudo chmod 600 /etc/ntfy/server.ymlntfy mit Docker Compose ausführen
Fügen Sie dies in /opt/ntfy/compose.yaml ein und ersetzen Sie 1000:1000 durch die beiden oben ausgegebenen Zahlen id -u und id -g.
services:
ntfy:
image: binwiederhier/ntfy:v2.27.0
container_name: ntfy
command: serve
user: "1000:1000"
environment:
- TZ=UTC
volumes:
- /etc/ntfy:/etc/ntfy
- /var/cache/ntfy:/var/cache/ntfy
- /var/lib/ntfy:/var/lib/ntfy
ports:
- "127.0.0.1:2586:2586"
restart: unless-stoppedcd /opt/ntfy
sudo docker compose up -d
sudo docker compose logs ntfy
curl -s http://127.0.0.1:2586/v1/healthEin gesunder Server antwortet auf {"healthy":true}. Zwei Details in dieser Compose-Datei sind absichtlich so festgelegt. Das Image ist auf v2.27.0 festgelegt, die aktuelle Version im August 2026, statt auf latest. Bei latest ändert das nächste docker compose pull die Serverversion, und Sie bemerken dies erst anschließend im Changelog. Der Port wird als 127.0.0.1:2586:2586 veröffentlicht. Der Container ist dadurch nur über die Loopback-Adresse des Hosts erreichbar. Verwenden Sie stattdessen 2586:2586, fügt Docker seine eigenen Firewall-Regeln vor Ihren Regeln ein. Der Port antwortet dann aus dem Internet, obwohl ufw status angibt, dass der Port geschlossen ist.
Wenn curl Connection refused ausgibt, lesen Sie das Container-Log. Ein Berechtigungsfehler bei /var/lib/ntfy/user.db bedeutet, dass die Zeile user: nicht mit dem Eigentümer dieser Verzeichnisse übereinstimmt. Der Prozess kann dadurch seine eigene Datenbank nicht erstellen und wird beendet. Der Leitfaden zu den Docker-Compose-Grundlagen für einen VPS behandelt den Eigentümer von Volumes und Neustartrichtlinien ausführlicher.
TLS mit Caddy vorschalten
Caddy fordert das Zertifikat selbstständig an und erneuert es. Das ist der kürzeste Weg zu funktionierendem TLS (Transport Layer Security).
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddyErsetzen Sie den Inhalt von /etc/caddy/Caddyfile durch drei Zeilen.
ntfy.example.com {
reverse_proxy 127.0.0.1:2586
}sudo systemctl reload caddy
curl -s https://ntfy.example.com/v1/healthDasselbe {"healthy":true} über HTTPS bedeutet, dass der gesamte Pfad funktioniert. Ein 502 von Caddy bedeutet, dass ntfy nicht lauscht: Prüfen Sie dies mit sudo ss -lntp | grep 2586. Ein Zertifikatsfehler bedeutet normalerweise, dass der DNS-Eintrag falsch ist oder Port 80 blockiert wird. sudo journalctl -u caddy -n 50 zeigt, welcher Fall vorliegt.
Wenn Sie bereits nginx betreiben, übernehmen Sie die von ntfy dokumentierten Proxy-Einstellungen: proxy_http_version 1.1, proxy_buffering off, proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for sowie Lese- und Sende-Timeouts von mindestens drei Minuten. Ein Subscriber hält eine HTTP-Verbindung so lange offen, wie er lauscht. nginx schließt eine inaktive Upstream-Verbindung standardmäßig nach 60 Sekunden. Dadurch verbinden sich Subscriber in einer Schleife neu, und während der Unterbrechung gesendete Nachrichten gehen verloren.
Benutzer anlegen und Themen absichern
Die Authentifizierung ist aktiviert, und bisher hat niemand Zugriff auf irgendetwas. Genau das ist beabsichtigt. Legen Sie ein Administratorkonto für sich selbst und ein Maschinenkonto für Skripte an. Diese Befehle lesen /etc/ntfy/server.yml aus dem Container. Deshalb ist die Konfigurationsdatei als Volume eingebunden.
sudo docker compose exec ntfy ntfy user add --role=admin admin
sudo docker compose exec ntfy ntfy user add robot
sudo docker compose exec ntfy ntfy user listFür jedes Konto werden Sie zur Eingabe eines Passworts aufgefordert. Ein Administrator ignoriert die Zugriffsliste und kann jedes Thema lesen und beschreiben. Verwenden Sie dieses Konto daher nur für sich selbst und die Telefon-App. robot ist ein normaler Benutzer ohne jeglichen Zugriff, bis Sie ihm Berechtigungen erteilen.
sudo docker compose exec ntfy ntfy access robot alerts write
sudo docker compose exec ntfy ntfy access robot "alerts_*" write
sudo docker compose exec ntfy ntfy accessEin ACL-Eintrag (Access Control List) besteht aus einem Benutzer, einem Thema und einer Berechtigung. Das Thema ist entweder ein konkreter Name oder ein Muster, in dem * für beliebige Zeichen steht. Damit deckt alerts_* die Themen alerts_backup und alerts_db ab, ohne dass Sie für jeden Host einen eigenen Befehl ausführen müssen. Die Berechtigung write bedeutet, dass nur veröffentlicht werden darf. Dadurch kann ein aus einem Cronjob gestohlenes Token keine Themen abonnieren und die gesendeten Daten zurücklesen. Mit dem speziellen Benutzernamen everyone legen Sie fest, was ein nicht authentifizierter Besucher tun darf. Verwenden Sie ihn nur, wenn Sie etwas bewusst öffentlich machen möchten, beispielsweise ntfy access everyone status read.
Skripte sollten ein Token und nicht Ihr Passwort verwenden.
sudo docker compose exec ntfy ntfy token add robotDer Befehl gibt ein Token aus, das mit tk_ beginnt. Ein Token übernimmt exakt die Berechtigungen des Benutzers, zu dem es gehört. Dieses Token kann daher in die Themen alerts veröffentlichen und sonst nichts tun. ntfy token list zeigt vorhandene Einträge an, und ntfy token remove widerruft einen Eintrag, ohne das Passwort des Benutzers zu ändern.
Ihre erste Nachricht senden und prüfen, ob die Sperre funktioniert
Prüfen Sie zunächst, ob die Tür geschlossen ist.
curl -s -o /dev/null -w '%{http_code}\n' -d "hello" https://ntfy.example.com/alertsDas gibt 403 aus. 403 ist die korrekte Antwort: auth-default-access: "deny-all" lehnt eine anonyme Veröffentlichung ab. Senden Sie jetzt eine echte Nachricht.
curl -H "Authorization: Bearer tk_REPLACE_WITH_YOUR_TOKEN" \
-H "Title: Nightly backup finished" \
-H "Priority: default" \
-H "Tags: white_check_mark" \
-d "42 GB copied in 11 minutes" \
https://ntfy.example.com/alertsDer Server antwortet mit der gespeicherten Nachricht als JSON. Daran erkennen Sie, dass sie angenommen und nicht verworfen wurde. Title ist die fett formatierte erste Zeile. Priority reicht von 1 bis 5 oder kann anhand des Namens von min bis urgent angegeben werden. Damit wird festgelegt, ob das Telefon einen Ton ausgibt. Tags werden in der Benachrichtigung zu Emoji, wenn der Name einem bekannten Emoji-Kurznamen entspricht. Andernfalls bleiben sie Klartext.
Um ein Topic in einem Terminal zu überwachen, streamen Sie es:
curl -s -u admin https://ntfy.example.com/alerts/rawcurl fordert das Passwort an. Jede Nachricht wird als eine Zeile empfangen. Die gelegentlich auftretenden Leerzeilen dienen als Keepalive-Nachrichten. Wenn Sie https://ntfy.example.com in einem Browser öffnen und sich mit demselben Konto anmelden, erhalten Sie die Web-App-Version desselben Streams.
Ratenbegrenzungen festlegen, damit ein einzelnes Skript den Server nicht überlasten kann
Standardmäßig erhält jeder Besucher ein Kontingent von 60 Anfragen. Es wird mit einer Anfrage alle 5 Sekunden wieder aufgefüllt. Für einen privaten Server ist das großzügig bemessen. Ein Skript, das in einer Wiederholungsschleife festhängt, verbraucht das Kontingent jedoch vollständig. Fügen Sie die Begrenzungen zu server.yml hinzu.
visitor-request-limit-burst: 30
visitor-request-limit-replenish: "10s"
visitor-message-daily-limit: 500sudo docker compose restart ntfyBei Überschreitung des Limits erhält ein Besucher HTTP 429. Die Nachricht wird dann nicht zugestellt. Das Limit wird pro Besucheradresse gezählt. Deshalb ist behind-proxy: true so wichtig: Ohne diese Einstellung erkennt ntfy nur die Adresse von Caddy. Dann zählen alle Clients als derselbe Besucher. Ein einziges lautes Skript kann dadurch das Kontingent aufbrauchen, das Ihr Telefon und Ihre anderen Server gemeinsam nutzen.
Alarmierung bei einem fehlgeschlagenen Cron-Job
Halten Sie das Token aus der Befehlszeile heraus. ps aux zeigt jedem Benutzer auf dem System die vollständige Befehlszeile jedes laufenden Prozesses an. Ein mit -H übergebenes Token ist daher für jedes lokale Konto sichtbar, solange curl läuft. Eine curl-Konfigurationsdatei verhindert das.
sudo install -d -m 700 /etc/ntfy-alert
printf 'header = "Authorization: Bearer tk_REPLACE_WITH_YOUR_TOKEN"\n' | sudo tee /etc/ntfy-alert/curlrc
sudo chmod 600 /etc/ntfy-alert/curlrcKapseln Sie den Job jetzt. Speichern Sie dies als /usr/local/bin/backup-with-alert.sh und machen Sie es mit chmod 750 ausführbar.
#!/bin/bash
out=$(/usr/local/bin/backup.sh 2>&1)
code=$?
if [ "$code" -ne 0 ]; then
printf '%s' "$out" | tail -c 1000 | curl -K /etc/ntfy-alert/curlrc \
-H "Title: backup.sh failed with exit $code" \
-H "Priority: high" \
-H "Tags: warning" \
--data-binary @- \
https://ntfy.example.com/alerts
fi
exit "$code"17 3 * * * /usr/local/bin/backup-with-alert.sh >> /var/log/backup-alert.log 2>&1$? wird in der Zeile unmittelbar nach dem Befehl erfasst, weil der nächste ausgeführte Befehl den Wert überschreiben würde. Die Ausgabe wird durch tail -c 1000 geleitet, weil ntfy eine maximale Nachrichtengröße erzwingt und eine Benachrichtigung kein Log-Viewer ist. Das abschließende exit "$code" bewahrt den ursprünglichen Status, sodass alle anderen Überwachungen dieses Jobs weiterhin einen Fehler erkennen. Testen Sie den gesamten Ablauf, indem Sie das Skript für einen Durchlauf auf /bin/false verweisen.
Ein Fehlerzweig, der nie ausgeführt wird, ist schlechter als gar keine Alarmierung, weil dadurch der Eindruck entsteht, dass Schweigen Erfolg bedeutet. Cron stellt Ihrem Job eine nahezu leere Umgebung und ein deutlich kürzeres PATH als Ihre Login-Shell bereit. Ein Skript, das bei manueller Ausführung funktioniert, kann daher beendet werden, bevor es die curl-Zeile erreicht. Der Leitfaden dazu, warum ein Cron-Job nicht ausgeführt wird behandelt diese Umgebungsprobleme. Verwenden Sie überall absolute Pfade und lesen Sie die Logdatei nach dem ersten geplanten Lauf, statt dies vorauszusetzen.
Alarm bei Fehlern einer systemd-Unit
Cron deckt geplante Aufgaben ab. Für lang laufende Dienste benötigen Sie OnFailure=. systemd führt es aus, sobald eine Unit in den Zustand failed wechselt. Erstellen Sie eine Template-Unit und verwenden Sie sie für jeden Dienst auf dem Server erneut. Speichern Sie sie als /etc/systemd/system/ntfy-unit-failed@.service.
[Unit]
Description=Send an ntfy alert because %i failed
[Service]
Type=oneshot
ExecStart=/usr/local/bin/ntfy-unit-failed %iSetzen Sie anschließend /usr/local/bin/ntfy-unit-failed auf den Modus 750:
#!/bin/bash
unit="$1"
journalctl -u "$unit" -n 15 --no-pager -o cat | tail -c 1000 | curl -K /etc/ntfy-alert/curlrc \
-H "Title: $unit failed on $(hostname -s)" \
-H "Priority: urgent" \
-H "Tags: rotating_light" \
--data-binary @- \
https://ntfy.example.com/alertsBinden Sie sie mit einer Drop-in-Konfiguration an einen Dienst an. Dadurch kann ein Paket-Upgrade Ihre Änderung nicht überschreiben.
sudo systemctl edit myapp.service[Unit]
OnFailure=ntfy-unit-failed@%n.service%n wird zum vollständigen Unit-Namen erweitert. Dadurch wird die Instanz zu ntfy-unit-failed@myapp.service. %i innerhalb des Templates übergibt myapp.service als erstes Argument an das Skript. So kann ein Template für jede Unit verwendet werden. Testen Sie die Funktion mit einer Unit, die absichtlich fehlschlägt. Speichern Sie sie als /etc/systemd/system/ntfy-selftest.service.
[Unit]
Description=Deliberately failing unit
OnFailure=ntfy-unit-failed@%n.service
[Service]
Type=oneshot
ExecStart=/bin/falsesudo systemctl daemon-reload
sudo systemctl start ntfy-selftest.serviceDer Startbefehl wird mit einem Exit-Status ungleich 0 beendet und gibt Job for ntfy-selftest.service failed because the control process exited with error code aus. Das Telefon sollte etwa eine Sekunde später vibrieren. Löschen Sie die Test-Unit anschließend.
Ein Fallstrick ist wichtig. OnFailure= wird nur ausgeführt, wenn eine Unit den Zustand failed erreicht. Ein Dienst mit Restart=always erreicht diesen Zustand möglicherweise nie, weil systemd ihn stattdessen weiter neu startet. Die Unit schlägt erst fehl, wenn sie innerhalb von StartLimitIntervalSec mehr als StartLimitBurst Neustarts durchführt. Setzen Sie diese beiden Werte bei jedem Dienst, über dessen Ausfall Sie informiert werden möchten. Andernfalls kann eine Neustartschleife tagelang unbemerkt weiterlaufen. Timer sind der sauberere Ersatz für das obige Cron-Muster, weil die Service-Unit eines Timers OnFailure= automatisch erhält. Der Leitfaden zu systemd-Diensten und Timern auf einem VPS beschreibt die Umstellung Schritt für Schritt.
Einen Uptime-Monitor in dasselbe Topic integrieren
Uptime Kuma, der selbst gehostete Statusmonitor, unterstützt einen ntfy-Benachrichtigungstyp. Öffnen Sie Settings, anschließend Notifications und dann Setup Notification. Wählen Sie Ntfy aus, setzen Sie die Server-URL auf https://ntfy.example.com und das Topic auf alerts, wählen Sie eine Priorität und fügen Sie das Zugriffstoken robot ein. Senden Sie die Testbenachrichtigung, bevor Sie speichern. Ein falscher Topic-Name bleibt bei einer write-Berechtigung, die diesen Topic nicht abdeckt, ohne Fehlermeldung.
Die ehrliche Einschränkung dieser Lösung: Ein Monitor auf derselben VPS kann nicht feststellen, dass die VPS ausgefallen ist. ntfy kann außerdem nicht melden, dass ntfy selbst ausgefallen ist. Betreiben Sie den Monitor auf einem anderen Rechner und geben Sie ihm einen zweiten Benachrichtigungskanal, beispielsweise E-Mail, für den Monitor, der ntfy selbst überwacht. Uptime Kumas Monitortyp Push deckt den anderen blinden Fleck ab: Ihr Cronjob ruft nach einem erfolgreichen Lauf eine Push-URL auf, und Kuma alarmiert, wenn diese Aufrufe ausbleiben. Ein Fehlerzweig wird nur ausgelöst, wenn der Job läuft. Er sagt daher nichts über einen Job aus, der nie gestartet wurde.
Funktioniert selbst gehostetes ntfy auf Android und dem iPhone?
Unter Android: ja, ohne Einschränkungen. Installieren Sie die App über Google Play oder F-Droid, öffnen Sie die Einstellungen, setzen Sie den Standardserver auf https://ntfy.example.com, fügen Sie Ihr Konto im Bereich für die Benutzerverwaltung hinzu und abonnieren Sie anschließend alerts. Die sofortige Zustellung hält einen Vordergrunddienst aktiv, damit Nachrichten auch im Doze-Modus des Telefons eintreffen. Die dauerhafte Benachrichtigung gehört zu den Android-Anforderungen für Vordergrunddienste und ist kein Fehler. Der F-Droid-Build enthält überhaupt keinen Firebase-Code. Daher verwendet jedes Abonnement die sofortige Zustellung. ntfy kann außerdem als UnifiedPush-Distributor fungieren, also als offene Alternative zum Push-Dienst von Google. Dadurch können auch andere Apps, die UnifiedPush unterstützen, über Ihren Server zustellen.
Unter iOS funktioniert es mit einer Abhängigkeit, die Sie nicht entfernen können. Apple weckt eine App im Hintergrund ausschließlich über APNs (Apple push notification service). Nur die Partei mit den Signaturzugangsdaten der App darf Nachrichten an sie senden. Ihr Server kann die App daher nicht direkt erreichen. ntfy löst das über ein Relay: Ihr Server sendet eine poll_request mit der Nachrichten-ID an ntfy.sh. ntfy.sh leitet sie über Firebase und APNs weiter, um die App zu wecken. Anschließend ruft die App den Nachrichtentext von Ihrem Server ab.
upstream-base-url: "https://ntfy.sh"Machen Sie sich klar, welche Folgen das hat. Der Nachrichteninhalt bleibt auf Ihrem Server. Die Tatsache, dass eine Nachricht eingetroffen ist, und ihre ID werden jedoch über eine Infrastruktur übertragen, die Sie nicht betreiben. Ohne diese Einstellung treffen Benachrichtigungen von einem selbst gehosteten Server auf dem iPhone verspätet oder gar nicht ein, weil nichts die App weckt. Das Relay lässt sich nur entfernen, wenn Sie die iOS-App selbst mit Ihrem eigenen Apple-Entwicklerkonto und Ihren eigenen APNs-Schlüsseln erstellen und veröffentlichen. Dafür fallen jährliche Gebühren an, und für jedes Update ist ein neuer Build erforderlich. Wenn ein Relay für Ihren Anwendungsfall nicht akzeptabel ist, verwenden Sie die Benachrichtigungen unter Android oder in der Desktop-Web-App.
Backups, Upgrades und Festlegen des Image-Tags
Zwei Pfade können nicht neu erzeugt werden: /etc/ntfy/server.yml und /var/lib/ntfy/user.db. Der zweite enthält alle Benutzer, Passwort-Hashes, ACL-Einträge und Token. Behandeln Sie ihn daher wie einen privaten Schlüssel.
sudo tar czf ntfy-backup.tgz -C / etc/ntfy var/lib/ntfy
sudo chmod 600 ntfy-backup.tgzKopieren Sie diese Datei vom Server weg. cache.db enthält nur aktuelle Nachrichten, und zwar 12 Stunden mit dem oben genannten cache-duration. Sein Verlust verursacht daher keinen schützenswerten Datenverlust. Für ein Upgrade ändern Sie den Tag in der Compose-Datei und führen den Pull aus.
sudo docker compose pull
sudo docker compose up -d
curl -s https://ntfy.example.com/v1/healthLesen Sie zuerst die Versionshinweise. Die SQLite-Datenbanken werden beim Start migriert. Nach einer Schemaänderung ist ein Rollback auf einen älteren Tag daher nicht sicher. Bewahren Sie das gerade erstellte Backup auf, bis die neue Version einen Tag lang ausgeführt wurde.
Gotify und Apprise
Gotify ist die kleinere Option: eine Binärdatei mit Weboberfläche und einer Android-App, ohne Topic-Wildcards und ohne offiziellen iOS-Client. Das eignet sich für einen privaten Server, bei dem Android das einzige Ziel ist. Apprise ist eine Python-Bibliothek und ein Kommandozeilenprogramm statt eines Servers. Damit lässt sich eine einzelne Nachricht an mehr als hundert Dienste verteilen, darunter ntfy. Das eignet sich für ein Skript, das mehrere Ziele gleichzeitig erreichen muss. ntfy bietet einen Server, eine HTTP-API und Apps für beide mobilen Plattformen. Deshalb ist ntfy die übliche Lösung für Benachrichtigungen von einem gemieteten Server aus.
FAQ
Warum liefert die Veröffentlichung an meinen ntfy-Server den Status 403?
Mit auth-default-access: "deny-all" in server.yml wird eine anonyme Veröffentlichung abgelehnt. Das ist beabsichtigt. Senden Sie Anmeldedaten mit -u user:pass oder -H "Authorization: Bearer tk_...". Wenn Sie bereits ein Token senden und weiterhin 403 erhalten, besitzt der Benutzer hinter diesem Token keinen passenden ACL-Eintrag für das Topic. Führen Sie ntfy access aus, um die vollständige Liste auszugeben. Beachten Sie, dass eine write-Berechtigung kein Abonnieren erlaubt. Ein Konto, das erfolgreich veröffentlicht, wird daher weiterhin abgelehnt, wenn es versucht, dasselbe Topic zu lesen.
Funktionieren Benachrichtigungen auf dem iPhone mit einem selbst gehosteten ntfy-Server?
Ja, über ein Relay, das Sie nicht umgehen können. Apple weckt Apps nur über APNs (Apple push notification service), und nur der Publisher der App kann dorthin senden. Daher leitet ntfy ein poll_request mit der Nachrichten-ID an ntfy.sh weiter. ntfy.sh überträgt es anschließend an das Gerät. Setzen Sie upstream-base-url: "https://ntfy.sh" in server.yml und starten Sie den Container neu. Der Nachrichtentext selbst wird weiterhin von Ihrem Server abgerufen. Ohne diese Einstellung werden iOS-Benachrichtigungen verzögert angezeigt oder erscheinen gar nicht.
Warum ist die ntfy-Benachrichtigung meines Cronjobs nie angekommen?
Führen Sie die curl-Zeile zunächst separat aus, um zu prüfen, ob Token und Topic korrekt sind. Wenn sie manuell funktioniert, aber nicht aus cron, liegt der Fehler vor der Benachrichtigung: cron führt Jobs mit einer minimalen Umgebung und einem kurzen PATH aus. Daher kann ein Script, das einen Befehl ohne vollständigen Pfad aufruft, beendet werden, bevor es die curl-Zeile erreicht. Verwenden Sie absolute Pfade, leiten Sie die Ausgabe des Jobs in eine Logdatei um und lesen Sie diese Datei nach dem nächsten Lauf. Eine 429-Antwort statt einer Zustellung bedeutet, dass das Rate-Limit funktioniert und Ihr Script zu schnell erneut versucht.
Sollte ich ntfy im öffentlichen Internet bereitstellen?
Die Smartphone-Apps müssen den Server aus Mobilfunknetzen erreichen können. Daher ist ein öffentlicher HTTPS-Endpunkt mit auth-default-access: "deny-all" und ACLs pro Topic die übliche Konfiguration. Sie ist sicher, solange kein Topic für everyone lesbar ist. Eine ausschließlich über VPN erreichbare Instanz ist sinnvoll, wenn jeder Abonnent ein von Ihnen kontrolliertes Gerät ist. Für Smartphones ist sie jedoch schlecht geeignet, weil die App nur bei bestehendem Tunnel Nachrichten empfängt. Benachrichtigungen werden daher gesammelt, bis das Smartphone die Verbindung wiederherstellt.