Gotify – dein kleiner Benachrichtigungs-Server (unter Docker)

Linux

Du kennst das sicher….du hast hier und da einen Dienst laufen und hättest gerne regelmäßig eine Benachrichtigung (Fenster offen, Heizung aus, Hütte brennt, Server down,…) und hättest gerne eine plattformunabhängige Benachrichtigungsmöglichkeit. Klar, du kannst das mit SMS (dafür gibt es Anbieter im Internet) oder z.B. mit Pushover bzw. Pushbullet lösen. Aber wenn du einen kleinen Server (und wenn es nur ein preiswerter vServer) hast, warum dann nicht den Notify-Server dort installieren.

Und schon sind wir mittendrin im Thema – ein kleiner, aber feiner Dienst dafür ist GOTIFY. Gotify selbst ist einen Server, den du recht einfach dank einer API mit Infos füttern kannst. Und los geht es mit der Installtion:

docker run -d -v /var/gotify/data:/app/data gotify/server
Unable to find image 'gotify/server:latest' locally
latest: Pulling from gotify/server
686b8aaade4d: Pull complete
ac96f9366792: Pull complete
e42bf3cc340b: Pull complete
383a3cca7220: Pull complete
Digest: sha256:09c79bc1e4032c7c3b1b808cfbe384226cb5cd27b86f2cb0876b7d20e1a8b3d4
Status: Downloaded newer image for gotify/server:latest
13b5246f7fde50b64e3748c3a58e74d08a703cca7be4962ee3e42280150e2fe8
...

Im o.a. Befehl habe ich bewusst auf das forwarden des Port 80 (-p 80:80) verzichtet, da ich einen NGINX Reverse Proxy laufen habe und dort das entsprechende Forwarding konfiguriere. Näheres dazu findest du auch hier im Blog. Weiterhin bietet es sich natürlich an, eine passende Subdomain im DNS einzutragen.

Nachdem diese Vorarbeit erledigt ist, solltest du mit https://gotify.DOMAIN.TLD (domain.tld ist natürlich abhängig von deinem Server) die Weboberfläche des Dienstes erreichen können. Die Credentials für den ersten Login lauten: admin/admin

Als erstes solltest du mit einem Klick auf admin oben rechts das Passwort ändern. Es ist unnötig, den Grund dafür zu erwähnen 🙂

Dann konfigurierst du dir eine App. Damit bekommst du einen Token, den du später benötigst, um Nachrichten an den Server zu senden.

Der Name der App ist freiwählbar, die Beschreibung ist empfehlenswert, aber nicht zwingend erforderlich.

Anschließend kannst du mit einem Klick auf das Auge dir den Token anzeigen lassen (hier im Beispiel habe ich ihn mal eingeblendet (du kannst dir einen versuch, mir damit eine Nachricht zu senden, ersparen 🙂 ).

Jetzt kannst du bequem auf der Kommandozeile eine erste Nachricht senden:

# curl -X POST "https://gotify.kwellkorn.de/message?token=A1GUHJpCnnLnvku" -F "title=Meine erste Nachricht" -F "message=Schön, das dies so einfach geklappt hat"

oder auch per HTTP

# http -f POST "https://gotify.kwellkorn.de/message?token=A1GUHJpCnnLnvku" "title=Meine erste Nachricht" "message=Schön, das dies so einfach geklappt hat"

In GOTIFY schaut das dann so aus:

Natürlich geht das auch bequem vom Smartphone aus:

Und das Ergebnis:

Über den Reiter Apps (und deren Token) kannst du unterscheiden, von welchem Dienst eine Nachricht kommt.

Eine Integration in Watchtower (Blogbeitrag siehe hier) kann dann z.B. so aussehen (siehe env-Variablen (-e)):

docker run --rm \ \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -e WATCHTOWER_NOTIFICATIONS=gotify \
    -e WATCHTOWER_NOTIFICATION_GOTIFY_URL="https://gotify.kwellkorn.de" \
    -e WATCHTOWER_NOTIFICATION_GOTIFY_TOKEN="A1GUHJpCnnLnvku" \
    containrrr/watchtower \
    --run-once \
    --cleanup \
    --include-restarting \
    --rolling-restart \
    --include-stopped
time="2022-02-12T11:31:21Z" level=info msg="Watchtower 1.4.0"
time="2022-02-12T11:31:21Z" level=info msg="Using notifications: gotify"
time="2022-02-12T11:31:21Z" level=info msg="Checking all containers (except explicitly disabled with label)"
time="2022-02-12T11:31:21Z" level=info msg="Running a one time update."
time="2022-02-12T11:31:44Z" level=info msg="Found new mariadb:10.5 image (448c94b60306)"
time="2022-02-12T11:31:59Z" level=info msg="Found new mailcow/sogo:1.106 image (9a9afd85fdf6)"
time="2022-02-12T11:32:09Z" level=info msg="Found new memcached:alpine image (31403aa3ac88)"
time="2022-02-12T11:32:14Z" level=info msg="Found new adguard/adguardhome:latest image (debe970b1d29)"
time="2022-02-12T11:32:20Z" level=info msg="Found new jamesits/ripe-atlas:latest image (fdf5831bd44b)"
time="2022-02-12T11:32:21Z" level=warning msg="Could not do a head request for \"maddud/hak5-cloud-c2:latest\", falling back to regular pull." container=/hak5-cloud-c2 image="maddud/hak5-cloud-c2:latest"
time="2022-02-12T11:32:21Z" level=warning msg="Reason: registry responded to head request with \"401 Unauthorized\", auth: \"Bearer realm=\\\"https://auth.docker.io/token\\\",service=\\\"registry.docker.io\\\",scope=\\\"repository:maddud/hak5-cloud-c2:pull\\\",error=\\\"insufficient_scope\\\"\"" container=/hak5-cloud-c2 image="maddud/hak5-cloud-c2:latest"
time="2022-02-12T11:32:23Z" level=info msg="Unable to update container \"/hak5-cloud-c2\": Error response from daemon: pull access denied for maddud/hak5-cloud-c2, repository does not exist or may require 'docker login': denied: requested access to the resource is denied. Proceeding to next."
time="2022-02-12T11:32:34Z" level=info msg="Found new mysql:5.7 image (0712d5dc1b14)"
time="2022-02-12T11:32:59Z" level=info msg="Found new jc21/nginx-proxy-manager:latest image (1e3cead8d516)"
time="2022-02-12T11:33:00Z" level=info msg="Stopping /nginxproxymanager_app_1 (b0e21c98000b) with SIGTERM"
time="2022-02-12T11:33:05Z" level=info msg="Creating /nginxproxymanager_app_1"
time="2022-02-12T11:33:05Z" level=info msg="Stopping /kwellkorn_db_wp_1 (3acffd15e69d) with SIGTERM"
time="2022-02-12T11:33:07Z" level=info msg="Creating /kwellkorn_db_wp_1"
time="2022-02-12T11:33:08Z" level=info msg="Stopping /ripe-atlas (b2ef613154fe) with SIGTERM"
time="2022-02-12T11:33:18Z" level=info msg="Creating /ripe-atlas"
time="2022-02-12T11:33:19Z" level=info msg="Stopping /adguardhome (3a4bf3973e88) with SIGTERM"
time="2022-02-12T11:33:20Z" level=info msg="Creating /adguardhome"
time="2022-02-12T11:33:21Z" level=info msg="Stopping /mailcowdockerized_memcached-mailcow_1 (b88b33f667c2) with SIGTERM"
time="2022-02-12T11:33:22Z" level=info msg="Creating /mailcowdockerized_memcached-mailcow_1"
time="2022-02-12T11:33:22Z" level=info msg="Stopping /mailcowdockerized_sogo-mailcow_1 (b76d14f14278) with SIGTERM"
time="2022-02-12T11:33:33Z" level=info msg="Creating /mailcowdockerized_sogo-mailcow_1"
time="2022-02-12T11:33:33Z" level=info msg="Stopping /mailcowdockerized_mysql-mailcow_1 (694c697973b5) with SIGTERM"
time="2022-02-12T11:33:34Z" level=info msg="Creating /mailcowdockerized_mysql-mailcow_1"
time="2022-02-12T11:33:35Z" level=info msg="Removing image bbb58017bf5b"
time="2022-02-12T11:33:35Z" level=info msg="Removing image c8ccb9a46cc5"
time="2022-02-12T11:33:36Z" level=info msg="Removing image efe813961a68"
time="2022-02-12T11:33:36Z" level=info msg="Removing image 4db72891d344"
time="2022-02-12T11:33:36Z" level=info msg="Removing image ed8fdaa3e2c6"
time="2022-02-12T11:33:41Z" level=info msg="Removing image 02b96c648297"
time="2022-02-12T11:33:41Z" level=info msg="Removing image 9f35042c6a98"
time="2022-02-12T11:33:41Z" level=info msg="Session done" Failed=0 Scanned=29 Updated=7 notify=no
time="2022-02-12T11:33:41Z" level=info msg="Waiting for the notification goroutine to finish" notify=no

Und das Ergebnis in der Web-UI:

Viel Erfolg bei deiner Umsetzung. 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert