Je migre mes différents services notifiant via Telegram vers le service autohébergé Gotify.
Introduction
En consultant mes autres articles, vous constaterez que j’utilise mes services avec des notifications via Telegram. Je fais cela afin de les avoir sur mon téléphone. Je trouve cela plus pratique que d’avoir des e-mails, surtout que ce dernier est un système plutôt lourd pour de simples petits messages.
L’utilisation d’un bot Telegram dans son utilisation me satisfait pleinement.
Mais le fait d’utiliser un service tiers pour mes services hébergés m’embête…
J’ai trouvé une solution auto-hebergée (et simple) avec Gotify,
un service de notification disponible en Docker.
Comme le montre l’animal à l’effigie du logo, le serveur est écrit en Go.
Gotify est implémenté avec une API Rest. On pourra donc simplement envoyer des messages par le biais de simples commandes cURL.
Voici un exemple de notifications (Home Assistant) sur Telegram et sur Gotify :
Nous allons donc voir ici comment l’installer (Docker + Apache Reverse Proxy) et comment l’on envoie des notifications pour les applications suivantes :
- Tests “à la main” via cURL
- Home Assistant
- Supervision : Nagios (oui j’utilise encore ce truc) et Grafana
- Autres intégrations : Script Git et autres (Linux)
Installation
J’ai fait une installation assez simple dans lequel je n’utilise pas de BDD externe (Gotify utilise alors une base SQLite). Pour faire autrement, je vous invite à regarder la documentation officielle.
Pour l’accès en HTTPS, j’utilise avec Apache en reverse-proxy avec un certificat Let’s Encrypt.
Remarque
Edit
J’utilise maintenant Traefik en lieu et place d’Apache.
J’ai donc mis à jour cet article (section Docker) pour contenir les deux versions.
Certificat Let’s Encrypt (Apache)
Cette partie étant déjà couvert ici et ici, je vous mets ici simplement une commande pour l’exemple de ce tutos :
sudo certbot certonly -d gotify.mondomaine.mu
Reverse-Proxy (Apache)
Pour le bon fonctionnement du proxy inverse, il faut activer certains modules :
sudo a2enmod proxy
sudo a2enmod proxy_wstunnel
sudo a2enmod proxy_http
sudo systemctl restart apache2
J’ai donc créé le fichier de configuration du site
(/etc/apache2/sites-available/gotify-rp.conf
) de la manière suivante
<VirtualHost *:80>
ServerName gotify.mondomaine.mu
ServerAdmin webmaster@mondomaine.mu
ErrorLog ${APACHE_LOG_DIR}/gotify-error.log
CustomLog ${APACHE_LOG_DIR}/gotify-access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =gotify.mondomaine.mu
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost *:443>
ServerName gotify.mondomaine.mu
ServerAdmin webmaster@mondomaine.mu
ErrorLog ${APACHE_LOG_DIR}/gotify-error.log
CustomLog ${APACHE_LOG_DIR}/gotify-access.log combined
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/gotify.mondomaine.mu/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/gotify.mondomaine.mu/privkey.pem
# https://gotify.net/docs/apache
Keepalive On
# The proxy must preserve the host because gotify verifies the host with the origin
# for WebSocket connections
ProxyPreserveHost On
# Proxy web socket requests to /stream
ProxyPass "/stream" ws://127.0.0.1:5858/stream retry=0 timeout=5
# Proxy all other requests to /
ProxyPass "/" http://127.0.0.1:5858/ retry=0 timeout=5
ProxyPassReverse / http://127.0.0.1:5858/
</VirtualHost>
Pensez à adapter votre URL ainsi que le port d’écoute. Vous l’aurez compris, mon conteneur Gotify sera exposé sur le port 5858. Si vous voulez faire autrement, éditez donc ce fichier ainsi que le Docker Compose de la partie suivante.
On met donc en service cette configuration :
sudo a2enconf gotify-rp.conf
sudo systemctl reload apache2
Docker
Dans le dossier où je stocke le Docker Compose (/root/docker/gotify
),
j’ai crée un fichier (.env
) contenant la variable d’environnement qui
correspond au mot de passe du compte admin.
Voici des commandes pour faire cela automatiquement :
sudo -i
mkdir -p /root/docker/gotify/data && cd /root/docker/gotify
echo -e "GOTIFY_DEFAULTUSER_PASS=$(pwgen -B 64 1)" > .env
mkdir -p /var/gotify/data
Docker Compose avec Apache :
version: "3"
services:
app:
image: gotify/server
container_name: gotify
restart: always
ports:
- 127.0.0.1:5858:80
env_file:
- .env
volumes:
- "/var/gotify/data:/app/data"
Docker Compose avec Traefik :
version: "3.8"
services:
app:
image: gotify/server
container_name: gotify
restart: always
env_file:
- .env
volumes:
- "/var/lib/gotify:/app/data"
labels:
- traefik.enable=true
- traefik.port=80
- traefik.http.routers.gotify.rule=Host(`gotify.mondomaine.mu`)
- traefik.http.routers.gotify.tls=true
- traefik.http.routers.gotify.tls.certresolver=mycertresolver
networks:
- proxy
networks:
proxy:
external:
name: traefik-net
Pourquoi il n’y a plus de section ports:
dans cette version ?
Réponse ici !
Comment la redirection en HTTPS se fait ?
Réponse ici !
Il vous faut donc créer le dossier pour les données mais si vous avez effectué les commandes bash du dessus c’est déjà fait 😉.
On “up” donc notre définition (docker-compose up -d
)
et on se rend sur l’adresse définie dans notre reverse-proxy :
https://gotify.mondomaine.mu
Configuration
Serveur
Une fois connecter avec votre mot de passe, on créé des tokens pour nos différentes applications. Pour cela, on va dans l’onglet “APPS” et l’on clique sur “CREATE APPLICATION”. En plus du nom, on peut ajouter une description. Une fois l’entrée validée, on peut uploader une image en cliquant sur l’icône représentant un nuage pour plus de visibilité.
Pour révéler le token de l’application, il suffit de cliquer sur l’œil.
Dans la suite de l’article, je prendrais Az3rTy
comme exemple de token.
Prenez soin d’utiliser celui propre à chaque “APPS” pour vos configurations.
Clients
Tests cURL
On effectue donc un test en reprenant l’un des exemples ci-dessous.
En utilisant le système de formulaire HTTP de cURL :
curl "https://gotify.mondomaine.mu/message?token=Az3rTy" \
-F "title=Test 1" \
-F "message=Salut 🌍" \
-F "priority=5"
curl "https://gotify.mondomaine.mu/message" \
-H "X-Gotify-Key: Az3rTy" \
-F "title=Test 1" \
-F "message=Salut 🌍" \
-F "priority=5"
En utilisant le format JSON :
curl "https://gotify.mondomaine.mu/message?token=Az3rTy" \
--header "Content-Type: application/json" \
--request POST \
--data '{"title":"Test 1","message":"Salut 🌍","priority":5}'
Remplacez bien l’URL ainsi que le token par les vôtres.
Pour connaitre toute l’étendue des possibilités, vous trouverez ici le lien de la documentation officielle de l’API REST écrit avec le framework Swagger.
Home Assistant
Il n’y a pas d’intégration “Gotify” sur Home Assistant mais on s’en tire sans soucis avec la plateforme de notification REST.
Voici donc la section à ajouter à votre fichier configuration.yaml
:
notify:
- name: gotify_admin
platform: rest
resource: https://gotify.mondomaine.mu/message
method: POST_JSON
headers:
X-Gotify-Key: Az3rTy
message_param_name: message
title_param_name: title
data:
priority: 10
Ceci est la méthode la plus simple, moi je fais autrement.
Astuce
Ma façon de faire
configuration.yaml
:
# Notifications
notify: !include notify.yaml
secrets.yaml
:
# Gotify (Notification)
gotify_token: Az3rTy
notify.yaml
:
|
|
Ensuite, après avoir vérifier la configuration et redémarrer HA,
on va dans l’onglet “Outils de développement” et on test notre
service de la manière suivante :
Pour CTRL+C + CTRL+V :
title: "Test 2"
message: "Etat Soleil : {{ states('sun.sun') }}"
Avec ce test, vous êtes censé recevoir la position du soleil (à savoir au-dessus ou en dessous de l’horizon).
Vous pouvez donc configurer vos notifications HA avec Gotify !
Bonus : Script de MAJ d’HA !
Supervision
Nagios
Pour les notifications Nagios, j’ai écrit un script Bash disponible sur mon Github. La procédure de mise en place est décrite sur la page, je ne vais donc pas la réécrire ici.
Grafana
Pour les alertes de Grafana, il suffit de choisir le type “webhook”
et de mettre l’URL contenant le token :
https://gotify.mondomaine.mu/message?token=Az3rTy
Ça ne sert à rien d’activer les images car elles ne sont pas prises en charge par Gotify. Enfin pour être plus précis, la manière dont Grafana envoie les images ne correspond pas à la méthode de Gotify.
Divers
Git
Mon NAS (Synology) a aussi le rôle de serveur Git.
Afin de m’assurer que le git push
est bien arrivé,
j’ai fait un script hook/post-receive
qui envoie
une notification pour le dépôt mis à jour.
Le script en question :
#!/bin/bash
export LANG=en_US.UTF-8
# Gotify credential
url="https://gotify.mondomaine.mu"
token="Az3rTy"
# Get git directory name
git_repo=$(basename "$PWD") # Get repo dir basename
git_repo=${git_repo//.git/} # Remove '.git' extension
# Processing notification content
## Title
title="🆙 "
title+="Git Push"
## Message
message="$git_repo updated"
# Finally cURLing !
curl_http_result=$(curl "${url}/message?token=${token}" -F "title=${title}" -F "message=${message}" -F "priority=8" --output /dev/null --silent --write-out %{http_code})
if [[ $? -ne 0 ]]; then
echo "FATAL ERROR: cURL command failed !"
exit 1
fi
# Check HTTP return code ("200" is OK)
if [[ $curl_http_result -ne 200 ]]; then
echo -e "FATAL ERROR: API call failed ! Return code is $curl_http_result instead of 200."
exit 2
fi
exit 0
Pour récupérer le nom du dépôt, ce script prend le nom du dossier parent
au dossier où est le script (hook
) et enlève l’extension “.git” de ce
dernier (qui est donc le nom du dossier représentant le dépôt).
Unattended upgrades
Mes serveurs sous Ubuntu utilisent unattended-upgrades pour effectuer les MAJs de sécurités automatiquement. Le système de notification ne fonctionne que par e-mail, donc pour être notifié par Telegram et maintenant Gotify, j’avais fait un script que j’ai mis à jour pour fonctionner avec Gotify :
#!/bin/bash
# Send Gotify notifications about
# ubuntu pending updates
# Gotify credential
url="https://gotify.mondomaine.mu"
token="Az3rTy"
# Server info
server_name=$(uname -n)
updates_available=$(cat /var/lib/update-notifier/updates-available | awk NF)
release=$(lsb_release -d | cut -d$'\t' -f2)
# Processing notification content
## Title
title="$server_name ($release)"
## Message
message="$updates_available"
# Finally cURLing !
curl_http_result=$(curl "${url}/message?token=${token}" -F "title=${title}" -F "message=${message}" -F "priority=5" --output /dev/null --silent --write-out %{http_code})
if [[ $? -ne 0 ]]; then
echo "FATAL ERROR: cURL command failed !"
exit 1
fi
# Check HTTP return code ("200" is OK)
if [[ $curl_http_result -ne 200 ]]; then
echo -e "FATAL ERROR: API call failed ! Return code is $curl_http_result instead of 200."
exit 2
fi
exit 0
Le crontab associé (tous les matins à 8h) :
0 8 * * * /usr/local/sbin/my-unattended-upgrades-notify.sh
Backup Rsync
Gotify ne permet pas de transmettre de fichiers (il est apparemment possible de faire pour des images). C’est un peu comme un serveur MQTT pour utilisateur. Du coup, mes scripts de backups dont je parle ici m’on demandé un peu plus de travail.
Ces scripts versions “notifications avec Gotify” sont sur mon GitHub.
Synology DSM 7
Ajout du 17/06/2023
A partir de la version 7, on peut faire fonctionner Gotify !
Voici les étapes à remplir dans le menu : Système > Notification > Service Push > Webhooks d’application
Remarque
Captures d’écran
Conclusion
J’ai trouvé en Gotify une solution efficace pour remplacer Telegram. De mon ressenti, ce système de notification est plus rapide que le bot Telegram.
La solution est simple à utiliser à gros coup de cURL. Il existe aussi une application en CLI que je n’ai pas testé vu que je me débrouille pour le push des messages. Elle semble avoir son intérêt pour le mode “watch” mais une fois de plus, je n’ai pas poussé mon analyse plus loin.