,

Prometheus et Grafana avec Docker Compose : Créer une Stack de Monitoring Self-Hosted

Server room data center representing a self-hosted Prometheus and Grafana Docker monitoring stack

La comparaison des outils de monitoring self-hosted explique pourquoi Prometheus et Grafana sont généralement la réponse une fois qu’un homelab dépasse le stade du tableau de bord mono-hôte. Voici la partie où on construit vraiment la stack. À la fin de ce guide, Prometheus collectera les métriques de votre hôte et de vos conteneurs, Grafana transformera ces métriques en tableaux de bord, et vous aurez un fichier docker-compose.yml que vous pourrez étendre à mesure que votre homelab grandit. C’est une après-midi de travail, pas un week-end, et l’essentiel de cette après-midi consiste juste à regarder les conteneurs démarrer.

Ce que vous allez construire

La stack comporte quatre éléments, et il est utile de savoir ce que fait chacun avant de coller un fichier de configuration :

  • Prometheus collecte (scrape) les métriques des cibles selon un planning et les stocke dans sa propre base de données de séries temporelles
  • node_exporter expose les métriques au niveau de l’hôte (CPU, RAM, disque, réseau) dans un format que Prometheus comprend
  • cAdvisor expose les métriques par conteneur, pour voir ce que chaque conteneur Docker consomme
  • Grafana se connecte à Prometheus comme source de données et transforme les métriques stockées en tableaux de bord, graphiques et alertes

Aucun de ces éléments ne fonctionne sans que les autres fassent leur part. Prometheus sans exporters n’a rien à scraper. Grafana sans Prometheus n’a rien à visualiser. C’est un pipeline, pas quatre applications indépendantes.

Prérequis

Docker et Docker Compose doivent être installés sur l’hôte, et il est utile d’avoir déjà un dossier réservé pour les fichiers de configuration de la stack. Rien ici n’exige une machine particulièrement puissante. Prometheus est le plus lourd du lot, mais pour un homelab classique avec quelques dizaines de cibles de scraping, 1 à 2 Go de RAM et un peu d’espace disque pour la rétention des métriques suffisent largement.

Le fichier docker-compose.yml

Créez un dossier de projet, et à l’intérieur, un docker-compose.yml avec ce qui suit :

version: "3.8"

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.retention.time=15d"

  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    restart: unless-stopped
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - "--path.procfs=/host/proc"
      - "--path.sysfs=/host/sys"
      - "--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)"
    ports:
      - "9100:9100"

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    restart: unless-stopped
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    ports:
      - "8080:8080"

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: unless-stopped
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=changeme

volumes:
  prometheus_data:
  grafana_data:

Changez GF_SECURITY_ADMIN_PASSWORD avant de démarrer quoi que ce soit, évidemment. Les volumes nommés conservent l’historique des métriques de Prometheus ainsi que les tableaux de bord et paramètres de Grafana à travers les redémarrages et mises à jour de conteneurs, ce qui compte plus qu’il n’y paraît la première fois qu’une mise à jour efface un tableau de bord que personne n’avait sauvegardé.

La configuration de scraping Prometheus

Prometheus a besoin qu’on lui indique quoi scraper et à quelle fréquence. Dans le même dossier, créez prometheus.yml :

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: "node-exporter"
    static_configs:
      - targets: ["node-exporter:9100"]

  - job_name: "cadvisor"
    static_configs:
      - targets: ["cadvisor:8080"]

Les noms de conteneurs du fichier compose (node-exporter, cadvisor) fonctionnent directement comme noms d’hôte ici, parce que Docker Compose place tous les services sur le même réseau par défaut. Un intervalle de scraping de 15 secondes est un défaut raisonnable : assez fréquent pour des tableaux de bord utiles, pas assez pour noyer Prometheus sous les données sur un petit homelab.

Démarrer la stack

Depuis le dossier du projet :

docker compose up -d

Attendez quelques secondes, puis vérifiez que les quatre conteneurs tournent avec docker compose ps. Prometheus devrait être joignable sur http://votre-ip-serveur:9090, et sa page Status → Targets vaut le coup d’œil en premier : elle liste chaque cible de scraping et si Prometheus arrive à la joindre. Si node-exporter ou cadvisor apparaissent comme « down » ici, c’est presque toujours un problème réseau dans le fichier compose plutôt qu’un souci avec Prometheus lui-même.

Connecter Grafana à Prometheus

Grafana est joignable sur http://votre-ip-serveur:3000. Connectez-vous avec admin et le mot de passe défini dans le fichier compose, puis :

  1. Allez dans Connections → Data sources → Add data source
  2. Choisissez Prometheus
  3. Réglez l’URL sur http://prometheus:9090 (le nom du conteneur, encore une fois, pas localhost, puisque Grafana interroge Prometheus via le réseau Docker)
  4. Save & test

Une confirmation verte signifie que Grafana arrive à interroger Prometheus avec succès. Si ça échoue, vérifiez d’abord que les deux conteneurs sont sur le même réseau Docker, ce qui sera le cas par défaut avec ce fichier compose sauf si quelque chose d’autre a été personnalisé. La documentation Grafana sur la source de données Prometheus couvre l’authentification et les options de requête au-delà de ce qui est nécessaire ici, ça vaut le coup d’œil une fois les bases en place.

Construire votre premier tableau de bord

Construire des tableaux de bord panneau par panneau est une vraie compétence, mais ce n’est pas par là qu’une première stack de monitoring devrait commencer. La fonction d’import de tableaux de bord de Grafana récupère des dashboards que d’autres personnes ont déjà construits et partagés publiquement, et pour node_exporter et cAdvisor en particulier, les options communautaires sont excellentes :

  1. Allez dans Dashboards → New → Import
  2. Entrez un ID de dashboard : 1860 est le dashboard standard « Node Exporter Full », et 893 est un bon dashboard cAdvisor pour les métriques de conteneurs
  3. Sélectionnez la source de données Prometheus créée plus tôt
  4. Import

Vous obtenez un tableau de bord fonctionnel et détaillé en environ deux minutes, un bien meilleur point de départ qu’une toile vide. Une fois qu’il est actif, il est facile de voir quels panneaux sont réellement consultés au quotidien et d’en construire des personnalisés pour tout ce que ces dashboards préconstruits ne couvrent pas.

Mettre en place une alerte basique

Un tableau de bord n’est utile que si quelqu’un le regarde réellement, c’est pourquoi les alertes comptent autant que les panneaux eux-mêmes. Grafana gère ça via ses propres règles d’alerte plutôt que via quoi que ce soit configuré directement dans Prometheus (Prometheus a bien son propre Alertmanager, mais pour une première mise en place, l’alerting intégré de Grafana est le chemin le plus simple). Une alerte basique sur l’espace disque ressemble à peu près à ça : créez une nouvelle règle d’alerte, basez-la sur une requête portant sur les métriques disque de node_exporter, fixez un seuil comme moins de 10% d’espace libre, et définissez combien de temps cette condition doit tenir avant de se déclencher réellement, pour qu’un pic bref qui se résorbe tout seul ne déclenche pas une fausse alerte. Les contact points, le terme de Grafana pour désigner où une alerte est envoyée, prennent en charge l’email, Slack, les webhooks et plusieurs autres intégrations d’emblée, configurés une fois sous Alerting → Contact points puis attachés aux règles qui doivent les utiliser.

Où Netdata s’intègre dans tout ça

Prometheus et Grafana sont conçus pour l’échelle et l’historique, pas pour le retour instantané. Un intervalle de scraping de 15 secondes signifie qu’un problème doit persister au moins ce laps de temps avant d’apparaître, et construire un nouveau panneau Grafana pour investiguer un problème en direct prend parfois plus de temps que le problème lui-même ne dure. C’est là que Netdata vaut la peine d’être exécuté à côté de cette stack plutôt qu’à sa place : pointez-le vers le même hôte, et il donne des métriques à la seconde sans le moindre tableau de bord à construire, dès que quelque chose semble anormal. Prometheus et Grafana restent le système de référence pour les tendances et les alertes ; Netdata devient l’outil réellement ouvert quand un conteneur commence à mal se comporter, là, maintenant. Le détail complet de quand chaque outil a du sens est dans la comparaison du monitoring self-hosted.

Ajouter davantage de cibles à mesure que votre homelab grandit

Cette stack à quatre conteneurs est un point de départ, pas le produit fini. La plupart des applications self-hosted qui exposent nativement des métriques Prometheus (ou via un exporter dédié) peuvent être ajoutées de la même façon que node-exporter et cAdvisor : ajoutez un nouveau bloc job_name à prometheus.yml avec l’hôte et le port de la cible, puis rechargez Prometheus sans redémarrer toute la stack en envoyant une requête POST à son endpoint /-/reload (ou lancez simplement docker compose restart prometheus si l’endpoint de rechargement n’est pas activé). Les ajouts courants incluent des exporters pour des bases de données spécifiques, blackbox_exporter pour les vérifications de niveau HTTP, et des exporters personnalisés que les logiciels self-hosted embarquent de plus en plus par défaut. La configuration de scraping grandit un job à la fois ; le docker-compose.yml n’a rarement plus besoin de changer une fois le schéma en place.

Exposer Grafana en toute sécurité

Ouvrir le port 3000 directement sur internet est une mauvaise idée pour tout ce qui a des identifiants de connexion attachés à votre infrastructure, et Grafana ne fait pas exception. Si les tableaux de bord doivent être joignables en dehors du réseau local, placez un reverse proxy devant plutôt que de rediriger le port directement. Nginx Proxy Manager est un choix courant pour ça : il gère le certificat Let’s Encrypt et permet à Grafana de tourner sur un sous-domaine en HTTPS sans toucher au port 3000 depuis l’extérieur. Pour la plupart des homelabs, cependant, la meilleure réponse est de ne pas exposer Grafana publiquement du tout. Un tunnel WireGuard qui ramène vers le réseau domestique garde les tableaux de bord privés tout en restant joignables depuis un téléphone.

Garder la stack opérationnelle

Modifier docker-compose.yml à la main et relancer docker compose up -d fonctionne très bien, mais ça cesse d’être amusant dès qu’il y a plus de quelques stacks à gérer. Portainer donne à cette stack une interface web pour mettre à jour les images, consulter les logs et redémarrer des conteneurs individuels sans avoir à se connecter en SSH à chaque fois. Ce n’est pas obligatoire, mais ça vaut la peine d’être connu avant que le homelab ne dépasse cette seule stack.

Une fois que tout ça tourne, la question naturelle suivante est de savoir si Prometheus et Grafana seuls couvrent tout ce qui mérite d’être surveillé, ou si les vérifications de disponibilité et les pages de statut publiques ont aussi leur place dans le tableau. C’est un outil différent, avec un métier différent, et ça mérite son propre guide.

Related guides