Guide de déploiement

Healthchecks sur VPS : surveiller ses tâches cron, self-hosted

Déployer sur un VPS Cloud →

Tutoriel

Healthchecks sur VPS : surveiller ses tâches cron, self-hosted

Self-hosting6 min de lecture4 étapes

Une tâche cron qui ne tourne plus ne fait aucun bruit. La sauvegarde nocturne échoue, la purge des journaux s'arrête, la synchronisation avec un fournisseur casse — et rien ne vous prévient, puisque rien ne s'exécute. Healthchecks est un outil open source (licence BSD-3) qui renverse le problème : chaque tâche envoie un ping à la fin de son exécution, et Healthchecks vous alerte quand ce ping n'arrive pas. Ce guide l'installe en un conteneur Docker sur un VPS, le place derrière un reverse proxy HTTPS et branche une première tâche cron.

Sommaire· Pourquoi surveiller ce qui doit s'exécuter, pas seulement ce qui répond1/10
  1. 01Pourquoi surveiller ce qui doit s'exécuter, pas seulement ce qui répond
  2. 02Ce que Healthchecks apporte
  3. 03Healthchecks face aux méthodes courantes
  4. 04Prérequis
  5. 05Installer Healthchecks avec Docker Compose
  6. 06Gardez les inscriptions fermées
  7. 07Brancher vos tâches cron
  8. 08Recevoir les alertes
  9. 09Dépannage
  10. 10Installation en un clic depuis le Marketplace ServOrbit

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 /start et /fail mesurent 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

HealthchecksMAILTO de cronMoniteur d'uptime
Alerte si la tâche ne démarre pasOuiNonNon
Alerte si la tâche échoueOui, code de sortie ou /failSeulement si elle écrit sur sa sortieNon
Durée d'exécutionMesuréeNonNon
Machines sans port ouvertOui, simple appel HTTPS sortantOuiNon, il faut joindre la cible
Canaux d'alertePlus de vingt intégrationsE-mail localSelon l'outil
Historique centraliséOui, par contrôleNonOui, 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

  1. Préparer le fichier .env

    Créez le répertoire de l'application et un fichier .env qui portera la clé secrète et l'adresse publique. Remplacez hc.example.com par votre domaine.

    mkdir -p /opt/healthchecks && cd /opt/healthchecks
    cat > .env <<EOF
    SECRET_KEY=$(openssl rand -hex 24)
    SITE_ROOT=https://hc.example.com
    EOF
  2. Créer le fichier Compose

    Placez ce docker-compose.yml dans 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: {}
  3. 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 createsuperuser
  4. Publier en HTTPS derrière nginx

    Ajoutez un bloc server pour votre domaine, avec un certificat Let's Encrypt, et transmettez les en-têtes d'origine : sans X-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.

Vos tâches planifiées sous surveillance, sur votre VPS

Un VPS ServOrbit Ubuntu 24.04 avec 1 Go de RAM suffit pour Healthchecks. Installation en un clic depuis le Marketplace, HTTPS sur votre domaine ou sur le sous-domaine gratuit du VPS, compte administrateur créé pour vous.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.

Écrire sur WhatsApps'ouvre dans un nouvel onglet