Si vous ne savez pas encore ce que sont Prometheus et Grafana, lisez notre article sur Prometheus vs Grafana. Si vous connaissez déjà la différence, voici comment les faire tourner ensemble.
Cet article est le volet pratique. Il déploie Prometheus, Grafana et Node Exporter sur un seul VPS avec Docker Compose, place HTTPS devant Grafana grâce à Caddy, importe le tableau de bord Node Exporter Full (ID 1860) et montre comment collecter les métriques d'un second VPS via WireGuard.
Le test initial d'avril 2026 tournait sur Ubuntu 24.04 LTS avec Docker Engine 27.x et Docker Compose v2.30. Les versions épinglées dans la configuration ci-dessous ont depuis été mises à jour vers les versions actuellement prises en charge. Lors de ce test initial à cinq hôtes, le hub consommait environ 300 Mo de RAM au repos et de 530 à 650 Mo en collecte continue.
En bref
- Le VPS hub fait tourner Prometheus, Grafana et Node Exporter dans une seule stack Compose, avec Caddy installé sur l'hôte comme reverse proxy.
- Prometheus et Grafana n'écoutent que sur 127.0.0.1. L'accès public passe par Caddy avec HTTPS automatique.
- Ajoutez d'autres serveurs en installant Node Exporter sur chacun et en ajoutant des entrées dans
prometheus.yml. - WireGuard est le chemin réseau recommandé entre le hub et les satellites. Le réseau privé fonctionne bien quand vos serveurs partagent déjà un réseau privé.
- Un VPS de 2 Go a suffi pour le test à cinq hôtes ci-dessous, mais considérez cela comme une référence plutôt qu'une règle fixe liée au nombre d'hôtes.
Ce que vous allez construire
Voici à quoi ressemblera l'installation une fois terminée, dans les grandes lignes.
+-------------------+
| Your laptop |
+---------+---------+
| HTTPS
v
+--------------------------+----------------------------+
| MONITORING HUB VPS (2 GB RAM starting point) |
| Caddy (reverse proxy, auto HTTPS) |
| Grafana (port 3000, only via Caddy) |
| Prometheus (port 9090, internal only) |
| Node Exporter (port 9100, scraped on localhost) |
+----+---------------------------------+----------------+
| |
| scrape over WireGuard | scrape over WG
v v
+----+--------+ +-----+-------+
| App VPS 1 | | App VPS 2 |
| Node Expo. | | Node Expo. |
+-------------+ +-------------+
Un seul VPS hub héberge toute la stack de monitoring. Chaque autre VPS que vous voulez surveiller ne fait tourner que Node Exporter. Prometheus, sur le hub, récupère les métriques de chacun. Grafana les affiche. Caddy s'occupe du HTTPS.
Ce dont vous avez besoin
Pour cette installation précise, il vous faut un VPS Ubuntu pour le hub, un nom de domaine et un accès sudo.
- Un VPS avec au moins 2 Go de RAM sous Ubuntu 24.04 LTS.
- Un nom de domaine avec un enregistrement A pointant vers l'IP publique du VPS (par exemple, grafana.example.com). Indispensable pour le HTTPS.
- Un accès root ou sudo via SSH.
Tout au long de ce guide, remplacez grafana.example.com par le sous-domaine que vous avez réellement fait pointer vers votre VPS de monitoring. Utilisez le même domaine dans la variable d'environnement Grafana, la vérification DNS et le Caddyfile.
Si vous ne voulez surveiller qu'un seul serveur et que vous n'avez pas encore besoin de HTTPS, vous pouvez lancer la stack Compose sur votre VPS existant sans la partie reverse proxy. Le reste du guide reste valable.
Lancez un VPS Ubuntu instantanément avec accès root et stockage NVMe.
Déployer un VPS UbuntuÉtape 1 : préparation du serveur
Connectez-vous en SSH au VPS hub avec un utilisateur disposant de sudo. Commencez par une mise à jour du système.
sudo apt update && sudo apt upgrade -y
Installez Docker Engine et le plugin Compose depuis le dépôt officiel de Docker.
# Install prerequisites
sudo apt install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Vérifiez que les deux sont bien installés.
docker --version
docker compose version
Les deux commandes doivent renvoyer une version sans erreur. Les versions exactes de Docker Engine et de Compose dépendront de ce que le dépôt officiel propose au moment de l'installation.
sudo usermod -aG docker $USER
Déconnectez-vous puis reconnectez-vous avant de continuer, pour que la nouvelle appartenance au groupe prenne effet. Le groupe docker confère en pratique des privilèges équivalents à root, n'y ajoutez donc que des administrateurs de confiance.
Configurez UFW pour autoriser SSH, HTTP et HTTPS sur le hub de monitoring. Le port 80 sert aux redirections HTTP vers HTTPS et à la validation ACME. Grafana, lui, reste derrière Caddy.
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
N'ouvrez pas les ports 3000, 9090 ou 9100 sur l'internet public. Ce n'est pas un hasard si les services de monitoring écoutent sur 127.0.0.1.
Étape 2 : la stack Compose
Créez un répertoire pour la stack et la configuration de Prometheus.
mkdir -p ~/monitoring/prometheus
cd ~/monitoring
Écrivez le fichier Compose.
# ~/monitoring/docker-compose.yml
services:
prometheus:
image: prom/prometheus:v3.13.2
container_name: prometheus
restart: unless-stopped
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
- '--web.enable-lifecycle'
- '--web.listen-address=127.0.0.1:9090'
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
network_mode: host
node-exporter:
image: prom/node-exporter:v1.12.1
container_name: node-exporter
restart: unless-stopped
pid: host
network_mode: host
command:
- '--path.rootfs=/host'
- '--web.listen-address=127.0.0.1:9100'
- '--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($$|/)'
volumes:
- '/:/host:ro,rslave'
grafana:
image: grafana/grafana:13.1.3
container_name: grafana
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_ROOT_URL=https://grafana.example.com
- GF_SERVER_HTTP_ADDR=127.0.0.1
volumes:
- grafana_data:/var/lib/grafana
network_mode: host
depends_on:
- prometheus
volumes:
prometheus_data:
grafana_data:
Écrivez maintenant la configuration de Prometheus.
# ~/monitoring/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
monitor: 'monitoring-hub'
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['127.0.0.1:9090']
- job_name: 'node'
static_configs:
- targets: ['127.0.0.1:9100']
labels:
host: 'monitoring-hub'
Créez un fichier .env contenant le mot de passe administrateur de Grafana. Choisissez un mot de passe robuste. Ne versionnez pas ce fichier dans git.
cat > ~/monitoring/.env <<'EOF'
GRAFANA_ADMIN_PASSWORD='replace-with-a-strong-password'
EOF
chmod 600 ~/monitoring/.env
Quelques options ci-dessus méritent une explication.
--web.listen-address=127.0.0.1:9090fait écouter Prometheus uniquement sur l'interface de bouclage de l'hôte. Le port 9090 reste ainsi hors du réseau public, tout en restant accessible à Grafana et à l'administration locale.--web.enable-lifecycleactivePOST /-/reload, ce qui vous permet d'appliquer les modifications de configuration de Prometheus sans redémarrer le conteneur.pid: host,network_mode: host, le montage bind de la racine de l'hôte et--path.rootfs=/hostdonnent au Node Exporter conteneurisé le contexte hôte dont il a besoin, au lieu de le limiter à son propre environnement de conteneur.GF_USERS_ALLOW_SIGN_UP=falseempêche les visiteurs de créer eux-mêmes un compte Grafana. Cela ne rend pas Grafana privé pour autant : la page de connexion reste accessible publiquement via Caddy.
Astuce de pro : Si vous préférez éviter l'installation manuelle, Cloudzy propose des déploiements en un clic pour Grafana et Prometheus . Le déploiement Prometheus peut également installer Node Exporter.
Étape 3 : premier démarrage et vérification
Démarrez la stack.
cd ~/monitoring
docker compose up -d
Patientez quelques secondes, puis vérifiez que les trois conteneurs tournent.
docker compose ps
Les trois services doivent afficher un état « running ».
Ouvrez un tunnel SSH depuis votre ordinateur portable pour vérifier la page des cibles de Prometheus.
ssh -L 9090:localhost:9090 your-user@your-vps-ip
Rendez-vous ensuite sur http://localhost:9090/targets dans votre navigateur. Vous devriez voir deux cibles, toutes deux à l'état UP :
prometheus UP http://127.0.0.1:9090/metrics
node UP http://127.0.0.1:9100/metrics
Si l'une des deux est DOWN, passez à la section Problèmes courants. Ne continuez pas tant que les deux ne sont pas UP.
Fermez le tunnel une fois la vérification des cibles terminée. Depuis l'extérieur du VPS, Prometheus ne restera accessible que par ce tunnel SSH. L'étape suivante expose Grafana en HTTPS.
Étape 4 : reverse proxy avec HTTPS grâce à Caddy
Caddy tient dans un seul binaire. Il gère le HTTPS automatiquement. Pour un reverse proxy à site unique, sa configuration est plus courte que le bloc Nginx équivalent.
Installez Caddy depuis le dépôt officiel.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
Avant l'étape suivante, vérifiez que votre enregistrement DNS A pour grafana.example.com pointe bien vers l'IP publique du VPS. Sans cela, la validation ACME échoue.
dig +short grafana.example.com
# Should print the VPS public IP
Modifiez le Caddyfile.
# /etc/caddy/Caddyfile
grafana.example.com {
reverse_proxy 127.0.0.1:3000
encode gzip
}
Rechargez Caddy.
sudo systemctl reload caddy
Caddy obtient et renouvelle automatiquement des certificats TLS reconnus publiquement via ACME, dès lors que le domaine pointe vers votre serveur et que les ports 80 et 443 sont joignables. Ouvrez https://grafana.example.com dans votre navigateur : vous devriez voir la page de connexion de Grafana sur une connexion HTTPS valide. Connectez-vous avec admin et le mot de passe de votre fichier .env.
Étape 5 : ajouter Prometheus comme source de données et importer le tableau de bord 1860
Dans l'interface de Grafana, allez dans Connexions > Sources de données > Ajouter une source de données et choisissez Prometheus.
Renseignez l'URL suivante :
http://127.0.0.1:9090
Dans cette configuration, Grafana et Prometheus partagent le réseau de l'hôte, tandis que Prometheus n'écoute que sur l'interface de bouclage. Cliquez sur Save & test et vérifiez que Grafana parvient à interroger l'API de Prometheus. Le message « Successfully queried the Prometheus API » doit s'afficher.
Importons maintenant le tableau de bord. Node Exporter Full (ID 1860, par rfmoz) est un tableau de bord communautaire très utilisé pour les métriques de Node Exporter. Il couvre le CPU, la mémoire, les E/S disque, le réseau, les descripteurs de fichiers et les températures matérielles lorsque l'hôte les expose. Il propose aussi des variables pour job et instance, il fonctionne donc en mode hub-and-spoke sans la moindre modification.
Aller à Tableaux de bord > Nouveau > Importer un tableau de bord, saisissez l'ID de tableau de bord 1860, sélectionnez votre source de données Prometheus et lancez l'import.
Le tableau de bord doit se remplir dès que votre cible Node Exporter est UP. Le tableau 1860 s'appuie aussi, pour certains panneaux, sur les collecteurs optionnels systemd et processes : un panneau isolé resté vide ne signifie donc pas forcément que la cible est cassée.
Étape 6 : ajouter un second VPS (hub-and-spoke)
Avant de démarrer Node Exporter, assurez-vous que l'IP privée sur laquelle vous comptez l'attacher existe déjà sur le second VPS. Si vous utilisez WireGuard, terminez d'abord sa configuration.
Sur le second VPS, installez Docker en reprenant la partie installation de Docker de l'étape 1, mais n'ouvrez pas les ports 80 ou 443 uniquement pour le monitoring. Lancez ensuite Node Exporter seul.
mkdir -p ~/node-exporter
cd ~/node-exporter
cat > docker-compose.yml <<'EOF'
services:
node-exporter:
image: prom/node-exporter:v1.12.1
container_name: node-exporter
restart: unless-stopped
pid: host
command:
- '--path.rootfs=/host'
- '--web.listen-address=10.10.0.2:9100' # bind to the private monitoring IP, never 0.0.0.0
volumes:
- '/:/host:ro,rslave'
network_mode: host
EOF
docker compose up -d
Remplacez 10.10.0.2 par l'IP privée de monitoring de ce serveur. Avec WireGuard, utilisez son IP WireGuard. Avec le réseau privé Cloudzy, utilisez l'IP de l'interface privée du VPS. Si UFW est déjà actif sur ce VPS, n'autorisez que le hub de monitoring à joindre Node Exporter. Par exemple, si l'IP privée du hub est 10.10.0.1 :
sudo ufw allow proto tcp from 10.10.0.1 to any port 9100
sudo ufw status
Remplacez 10.10.0.1 par l'IP privée réelle du hub. Si UFW est inactif, l'option explicite --web.listen-address empêche toujours Node Exporter d'écouter sur l'interface publique, mais d'autres machines ayant accès à ce réseau privé peuvent elles aussi atteindre le port 9100.
Deux bonnes options pour le chemin réseau entre le hub et les satellites :
- Réseau WireGuard. Chaque VPS rejoint un réseau WireGuard et Prometheus interroge des IP privées. C'est l'option la plus sûre, une fois WireGuard configuré. Nous proposons WireGuard en déploiement en un clic, et nous avons aussi un tutoriel de configuration existant à ce sujet.
- Réseau privé Cloudzy. Les instances VPS Cloudzy situées dans la même région disposent d'une interface privée pour le trafic est-ouest : vous pouvez donc interroger cette adresse plutôt que de monter un tunnel WireGuard séparé.
Une fois Node Exporter en service sur le second VPS et joignable sur son IP privée, remplacez le job node existant dans prometheus.yml sur le hub par le bloc ci-dessous.
# Update the existing 'node' job in ~/monitoring/prometheus/prometheus.yml
- job_name: 'node'
static_configs:
- targets: ['127.0.0.1:9100']
labels:
host: 'monitoring-hub'
- targets: ['10.10.0.2:9100']
labels:
host: 'app-vps-1'
tier: 'production'
Rechargez Prometheus sans redémarrer le conteneur.
curl -X POST http://localhost:9090/-/reload
Rouvrez le tunnel SSH de l'étape 3, puis rendez-vous sur http://localhost:9090/targets. La nouvelle cible doit apparaître en UP. Ouvrez le tableau de bord Node Exporter Full, basculez la variable instance en haut vers le nouveau serveur et ses graphiques doivent s'afficher.
Consommation de ressources et quand passer à la taille supérieure
Ces chiffres proviennent du test initial d'avril 2026, sur un VPS Ubuntu de 2 Go surveillant cinq hôtes. Considérez-les comme une référence pour cette charge de travail, pas comme une garantie de dimensionnement pour les versions plus récentes.
| Composant | RAM au repos | RAM en activité (1 hôte) | RAM avec 5 hôtes | Disque (rétention 15 j, 5 hôtes) |
|---|---|---|---|---|
| Prometheus | ~100 MB | ~150 MB | ~250-350 Mo | ~500 Mo à 1,5 Go |
| Grafana | ~150 MB | ~180 MB | ~200 MB | ~50 MB |
| Node Exporter | ~15 Mo | ~20 Mo | sans objet | négligeable |
| Caddy | ~30 MB | ~40 Mo | ~40 Mo | sans objet |
| Total du hub | ~300 Mo | ~390 Mo | ~530-650 Mo | ~1,5 Go de données actives |
Passez à la taille supérieure quand le hub commence à manquer de mémoire ou de marge disque. Le seul nombre d'hôtes est un mauvais déclencheur de dimensionnement, car la cardinalité des séries, les collecteurs activés, l'intervalle de collecte et la rétention modifient tous l'empreinte. Pour du stockage centralisé sur le long terme, Prometheus prend en charge des intégrations de stockage distant. VictoriaMetrics est une option compatible Prometheus.
Problèmes courants
Les sept problèmes les plus fréquents, avec leurs correctifs.
- Prometheus accessible depuis l'internet public. Un simple mappage de port 9090:9090 expose Prometheus au monde entier. Correctif : conservez
--web.listen-address=127.0.0.1:9090dans la commande Prometheus, comme montré plus haut. Prometheus n'écoute alors que sur l'interface de bouclage de l'hôte. - La source de données Grafana n'arrive pas à joindre Prometheus. Cette stack utilise le réseau de l'hôte, Grafana peut donc joindre Prometheus sur http://127.0.0.1:9090. Vérifiez que Prometheus tourne et écoute toujours sur l'interface de bouclage.
- Le tableau de bord Node Exporter affiche « No data ». Trois causes habituelles. (a) Prometheus n'interroge pas la cible. Vérifiez
/targets. (b) Le label job dans la variable du tableau de bord ne correspond pas aujob_namedans la configuration de collecte. (c) Un pare-feu bloque le port 9100 entre le hub et la cible. - Le mot de passe administrateur de Grafana est resté
admin/adminen production. DéfinirGF_SECURITY_ADMIN_PASSWORDdepuis un fichier .env avant le tout premier démarrage. Si vous avez oublié, changez-le à la première connexion et désactivez l'inscription. - Caddy renvoie « ACME challenge failed ». L'enregistrement DNS A ne s'est pas encore propagé, ou le port 80 est bloqué. Lancez
ufw allow 80,443/tcp, attendez la propagation DNS, puis lancezsudo systemctl reload caddy. Utilisezdig +shortpour confirmer la propagation. - Le disque de Prometheus se remplit. Des labels à forte cardinalité ou des intervalles de collecte trop courts sur de nombreux hôtes peuvent remplir le volume très vite. Surveillez
prometheus_tsdb_head_serieset la taille du volume. Pour y remédier : désactivez les collecteurs Node Exporter inutilisés, allongezscrape_intervalà 30s, ou réduisez la rétention. - Erreurs de permissions sur les montages bind. Si vous montez un répertoire de l'hôte plutôt qu'un volume nommé, l'UID du conteneur (65534 pour Prometheus, 472 pour Grafana) doit avoir un accès en écriture. Les volumes nommés, comme dans le fichier Compose ci-dessus, évitent ce problème.
Quand cette stack est disproportionnée
Si vous voulez seulement une alerte quand une URL cesse de répondre, cette stack est disproportionnée. Uptime Kuma est bien plus léger si de simples contrôles de disponibilité vous suffisent.
Foire aux questions
Quelle est la différence entre Prometheus et Grafana ?
Prometheus est une base de données de séries temporelles : elle collecte les métriques des cibles configurées à l'intervalle que vous définissez, les stocke sur disque et répond aux requêtes PromQL. Grafana est une couche de visualisation qui se connecte à Prometheus (et à beaucoup d'autres sources) et affiche des tableaux de bord. Dans la quasi-totalité des cas, il vous faut les deux : Prometheus pour collecter et stocker, Grafana pour afficher.
De combien de RAM une installation Prometheus + Grafana a-t-elle besoin ?
Un hub de monitoring faisant tourner Prometheus, Grafana, Node Exporter et un reverse proxy sur un seul VPS consomme environ 300 Mo de RAM au repos, et de 530 à 650 Mo lorsqu'il collecte activement cinq hôtes toutes les 15 secondes.
Puis-je surveiller plusieurs serveurs avec une seule instance Grafana ?
Oui. Le schéma classique est le hub-and-spoke. Une seule instance Prometheus, sur un VPS hub, interroge le Node Exporter installé sur chaque autre serveur à surveiller. Grafana, sur le hub, interroge cet unique Prometheus. Le tableau de bord Node Exporter Full (ID 1860) propose une variable instance : vous passez d'un serveur à l'autre depuis un seul tableau de bord.
Quel est le meilleur tableau de bord Grafana pour Node Exporter ?
Pour cette installation, Node Exporter Full (tableau de bord ID 1860, par rfmoz) est un excellent choix par défaut. Il couvre les principales métriques hôtes de Node Exporter et prend en charge les variables job et instance pour la surveillance multi-serveurs. Certains panneaux dépendent de collecteurs Node Exporter optionnels : un panneau isolé resté vide ne signifie donc pas nécessairement que la cible est cassée.
Comment exposer Grafana en HTTPS ?
Faites tourner Grafana attaché à 127.0.0.1:3000 et placez devant lui un reverse proxy qui gère le HTTPS. Caddy est l'option la plus simple : un Caddyfile de quatre lignes avec reverse_proxy 127.0.0.1:3000 et un bloc de domaine fait tout le travail, y compris la gestion automatique des certificats TLS.
Prometheus + Grafana sont-ils gratuits pour un usage commercial ?
Prometheus est sous licence Apache 2.0. Grafana OSS est sous AGPLv3. L'usage interne et commercial de Grafana OSS non modifié est autorisé, mais le modifier, le distribuer ou proposer une version modifiée via un réseau peut créer des obligations de partage du code source au titre de l'AGPL. Grafana Enterprise et Grafana Cloud relèvent de conditions commerciales distinctes.
Quand faut-il passer de Prometheus à VictoriaMetrics ?
Envisagez VictoriaMetrics quand une rétention plus longue, une forte cardinalité des séries ou plusieurs instances Prometheus rendent la TSDB locale de Prometheus difficile à exploiter dans le budget mémoire et disque de votre serveur. VictoriaMetrics peut recevoir les données de Prometheus et exposer une API de requêtes compatible Prometheus : elle peut donc servir de stockage long terme ou de backend de métriques pour Grafana. Testez-la sur votre propre charge plutôt que de basculer à un seuil de RAM fixe.
