Ich nutze für regelmäßige Backups von Daten (z.B. Nextcloud) ein kleines Script, das Restic verwendet. Ich hatte allerdings schon mehrfach den Fall, dass ein Backup nicht sauber durchlief und das Backup-Repository damit gesperrt war und weitere Backups fehlschlugen, was ich dann natürlich erst Wochen (okay, Monate) später bemerkt habe.
Abhilfe schafft hier das Tool Healthchecks (https://github.com/healthchecks/healthchecks). Das funktioniert so, dass man Checks einrichtet und dafür eine Webhook-URL bekommt. In einem Script ruft man dann diese URL auf und setzt damit den Timer zurück. Sofern der Webhook nicht innerhalb der richtigen Zeit aufgerufen wird, wird ein Alert ausgelöst. Insgesamt also recht simpel.
Installation
Ich nutze hier, wie üblich, Docker. Hier meine docker-compose.yml:
services:
healthchecks:
image: healthchecks/healthchecks:latest
container_name: healthchecks
environment:
- DB=sqlite
- DB_NAME=/data/hc.sqlite
- DEBUG=False
- DEFAULT_FROM_EMAIL=me@example.com
- EMAIL_HOST=smtp.example.com
- EMAIL_HOST_PASSWORD=MyMailPassword
- EMAIL_HOST_USER=me@example.com
- EMAIL_PORT=587
- EMAIL_USE_TLS=True
- SECRET_KEY=Hok4K0Va6EwaYltk4ah7muc223rUVmz3
- SITE_ROOT=https://checks.example.com
- DISCORD_CLIENT_ID=123123
- DISCORD_CLIENT_SECRET=123123
- REGISTRATION_OPEN=False
ports:
- 8000:8000
volumes:
- ./data:/data
restart: unless-stopped
REGISTRATION_OPEN muss initial auf True gestellt werden, damit man sich selbst registrieren kann, danach sollte das allerdings wieder auf False gesetzt werden, damit sich keine fremden User registrieren können. Ich habe hier direkt die Discord-Integration eingerichtet, damit ich auf dem Weg auch Notifications verschicken kann. Die beiden Variablen sind aber natürlich optional.
Das Datenverzeichnis muss die richtigen Zugriffsrechte haben, damit der Container starten kann. Das geht schnell mittels
mkdir ./data
chown -R 999:999 ./data
Danach lässt sich der Stack mit docker compose up -d starten und die Seite aufrufen. Dort kann man sich dann mit einer E-Mail-Adresse registrieren.
Einbindung in ein Script
Um jetzt einen Check einzurichten, muss zuerst im Webinterface ein neuer Check erstellt werden. Dabei wird auch das normale Intervall (z.B. täglich) sowie eine Karenzzeit eingestellt.
Nun wird eine Check-URL angezeigt, ich nehme hier https://checks.example.com/ping/bla-bla-blub als Beispiel.
Simpler Check
Für einen einfachen Check, ob das Script gelaufen ist, reicht es, einen Befehl wie z.B.
curl -fsS -m 10 --retry 5 https://checks.example.com/ping/bla-bla-blub
mit der Check-URL auszuführen. Der Befehl sollte im Script als letztes ausgeführt werden, damit er erst ausgeführt wird, wenn alles andere funktioniert hat.
Check mit Laufzeitberechnung
Healthchecks kann auch die Laufzeit eines Scripts mit prüfen. Dazu wird erst der Endpunkt https://checks.example.com/ping/bla-bla-blub/start aufgerufen und nach Fertigstellung dann https://checks.example.com/ping/bla-bla-blub. Hierbei sollte auch noch eine Request-ID mitgegeben werden, um die einzelnen Ausführungen voneinander unterscheiden zu können.
Ich habe das bspw. so umgesetzt:
RID=`uuidgen`
HEALTHCHECK_ID=bla-bla-blub
curl -fsS -m 10 --retry 5 https://checks.example.com/ping/$HEALTHCHECK_ID/start?rid=$RID
# do backup
curl -fsS -m 10 --retry 5 https://checks.example.com/ping/$HEALTHCHECK_ID?rid=$RID
Nachdem das Script ausgeführt wurde, sieht das im Webinterface so aus:
Ausgeführter Check
Sollte ein Check nicht innerhalb der eingestellten Zeit aufgerufen werden, wird eine Notification ausgelöst. So sollte ich in Zukunft fehlschlagende Backups schneller bemerken.