Pourquoi surveiller ce qui doit s'exécuter, pas seulement ce qui répond
Un moniteur d'uptime vérifie qu'un service répond. Il ne voit pas ce qui se passe entre deux requêtes : la sauvegarde de 3 h, l'envoi des factures, le renouvellement d'un certificat, l'export vers le comptable. Ces tâches échouent en silence — un disque plein, un mot de passe expiré, un serveur redémarré sans son timer — et l'on s'en aperçoit le jour où l'on en a besoin.
La variable MAILTO de cron n'aide guère : elle n'envoie un message que si la tâche s'exécute et écrit sur sa sortie, et elle ne dit rien quand la tâche ne démarre pas du tout. Healthchecks part de l'absence : chaque tâche a une planification attendue, et le silence au-delà du délai de grâce déclenche l'alerte.
Ce que Healthchecks apporte
- Surveillance par ping — chaque tâche appelle une URL unique ; l'absence de ping déclenche l'alerte.
- Planification cron ou par période — expression cron avec fuseau horaire, ou intervalle simple, plus un délai de grâce.
- Durée d'exécution — les pings
/startet/failmesurent la durée et signalent les échecs explicites. - Codes de sortie et journaux — le code de sortie et la fin de la sortie de la commande, consultables dans le tableau de bord.
- Plus de vingt intégrations — e-mail, webhook, Slack, Discord, Matrix, ntfy, Telegram, Gotify, PagerDuty, Opsgenie…
- Équipe et API — projets séparés, membres invités, badges de statut et API REST pour créer les contrôles depuis vos scripts.
Healthchecks face aux méthodes courantes
Faites défiler le tableau
| Healthchecks | MAILTO de cron | Moniteur d'uptime | |
|---|---|---|---|
| Alerte si la tâche ne démarre pas | Oui | Non | Non |
| Alerte si la tâche échoue | Oui, code de sortie ou /fail | Seulement si elle écrit sur sa sortie | Non |
| Durée d'exécution | Mesurée | Non | Non |
| Machines sans port ouvert | Oui, simple appel HTTPS sortant | Oui | Non, il faut joindre la cible |
| Canaux d'alerte | Plus de vingt intégrations | E-mail local | Selon l'outil |
| Historique centralisé | Oui, par contrôle | Non | Oui, pour les services |
Prérequis
Un VPS Ubuntu 24.04 avec 1 Go de RAM suffit : Healthchecks tourne en un seul conteneur et stocke ses données dans une base SQLite. Il vous faut Docker avec le plugin Compose, et un nom de domaine pointant vers le VPS, avec nginx et un certificat HTTPS : les URL de ping et les liens des alertes sont construits sur cette adresse, et l'application refuse les requêtes adressées à un autre nom.
Idéalement, installez Healthchecks sur une machine distincte des serveurs qu'il surveille : s'il tombe avec eux, personne ne vous préviendra.
Installer Healthchecks avec Docker Compose
Préparer le fichier .env
Créez le répertoire de l'application et un fichier
.envqui portera la clé secrète et l'adresse publique. Remplacezhc.example.compar votre domaine.mkdir -p /opt/healthchecks && cd /opt/healthchecks cat > .env <<EOF SECRET_KEY=$(openssl rand -hex 24) SITE_ROOT=https://hc.example.com EOFCréer le fichier Compose
Placez ce
docker-compose.ymldans le même répertoire. Le port n'est publié que sur la boucle locale, les inscriptions publiques sont fermées et la base SQLite vit dans un volume.services: healthchecks: image: healthchecks/healthchecks:v5.0.1 restart: unless-stopped ports: - "127.0.0.1:8102:8000" env_file: .env environment: DEBUG: "False" DB_NAME: /data/hc.sqlite REGISTRATION_OPEN: "False" GUNICORN_WORKERS: "2" volumes: - healthchecks-data:/data volumes: healthchecks-data: {}Démarrer et créer le compte administrateur
Au démarrage, le conteneur applique les migrations puis lance le serveur web et les processus d'envoi d'alertes. Créez ensuite votre compte : la commande demande une adresse e-mail et un mot de passe.
docker compose up -d docker compose exec healthchecks ./manage.py createsuperuserPublier en HTTPS derrière nginx
Ajoutez un bloc
serverpour votre domaine, avec un certificat Let's Encrypt, et transmettez les en-têtes d'origine : sansX-Forwarded-Proto, la connexion échoue sur une erreur CSRF.location / { proxy_pass http://127.0.0.1:8102; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
Gardez les inscriptions fermées
Par défaut, Healthchecks accepte les inscriptions publiques. REGISTRATION_OPEN: "False" les ferme : seuls les comptes que vous créez ou que vous invitez dans un projet peuvent se connecter. Sur un serveur exposé à Internet, c'est le réglage à poser dès le premier démarrage.
Brancher vos tâches cron
Dans le tableau de bord, créez un contrôle, indiquez la planification — l'expression cron de la tâche et son fuseau horaire — puis un délai de grâce qui couvre sa durée normale. Copiez l'URL de ping et ajoutez-la à la tâche.
# crontab : sauvegarde à 3 h, ping seulement en cas de succès
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 5 -o /dev/null https://hc.example.com/ping/<uuid>
# variante : signaler le début, puis transmettre le code de sortie
URL=https://hc.example.com/ping/<uuid>
curl -fsS -m 10 --retry 5 -o /dev/null "$URL/start"
/usr/local/bin/backup.sh > /tmp/backup.log 2>&1
curl -fsS -m 10 --retry 5 -o /dev/null --data-binary @/tmp/backup.log "$URL/$?"La première forme ne pinge qu'en cas de succès : un échec se traduit par un ping manquant, donc une alerte au bout du délai de grâce. La seconde est plus parlante : /start mesure la durée, le code de sortie transmis à la place du ping signale l'échec immédiatement, et la sortie envoyée dans le corps de la requête s'affiche dans l'historique du contrôle. Les options -m 10 --retry 5 évitent qu'un réseau capricieux bloque la tâche ou fasse croire à une panne.
Recevoir les alertes
Dans Intégrations, ajoutez au moins un canal que vous lisez vraiment, puis associez-le à vos contrôles. Webhook, Slack (webhook entrant), Mattermost, ntfy et Gotify fonctionnent sans configuration côté serveur. D'autres intégrations demandent des identifiants déclarés dans le .env : un jeton de bot pour Telegram, un compte et un jeton pour Matrix, une application OAuth pour Discord.
Les alertes par e-mail passent par un serveur SMTP : ajoutez EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD et DEFAULT_FROM_EMAIL au fichier .env, puis relancez avec docker compose up -d. Les mêmes réglages servent aux invitations d'équipe et aux rapports périodiques.
Dépannage
La page renvoie une erreur 400. La requête n'arrive pas avec le bon nom d'hôte : vérifiez que SITE_ROOT correspond exactement au domaine servi par nginx, et que le bloc location transmet l'en-tête Host.
La connexion échoue avec une erreur CSRF. nginx ne transmet pas X-Forwarded-Proto : l'application croit recevoir du HTTP alors que le navigateur parle HTTPS. Ajoutez l'en-tête et rechargez nginx.
Un contrôle passe en alerte alors que la tâche a tourné. Le ping n'est pas parti : testez la commande curl à la main depuis la machine concernée, vérifiez l'accès sortant en HTTPS, et allongez le délai de grâce si la tâche dure plus longtemps que prévu.
Aucun e-mail n'arrive. Sans EMAIL_HOST, Healthchecks n'envoie rien et l'indique dans ses journaux au démarrage : consultez docker compose logs healthchecks.
Installation en un clic depuis le Marketplace ServOrbit
Le Marketplace ServOrbit installe Healthchecks sur votre VPS sans ligne de commande : il déploie le conteneur avec les inscriptions fermées, crée le compte administrateur avec un mot de passe généré, et publie l'application en HTTPS sur un sous-domaine de votre domaine ou sur le sous-domaine gratuit du VPS. L'identifiant et le mot de passe s'affichent dans votre espace client ; il ne reste qu'à créer vos contrôles.