Pendant longtemps, ma supervision se résumait à ça : je me connectais en SSH sur un serveur quand quelque chose semblait lent, je faisais un htop, je regardais si la RAM était pleine, et je passais à autre chose. Pour des incidents qui se produisent à 3h du matin, c'est évidemment inutile. J'ai découvert un VPS à court de disque deux jours après qu'il ait commencé à rejeter des requêtes — les logs de Traefik étaient saturés depuis le début mais personne ne les regardait.
J'avais essayé Netdata. Trop lourd pour des petits VPS à 4 Go de RAM où chaque ressource compte. Grafana + Prometheus ? Overkill pour ce que je voulais faire, et une demi-journée de configuration pour avoir un dashboard basique. Ce que je cherchais, c'était simple : voir en un coup d'œil l'état de toutes mes machines, et recevoir une notification sur mon téléphone quand quelque chose déraille.
Beszel fait exactement ça, sans rien de plus. Léger, rapide à déployer, et il s'intègre parfaitement dans mon environnement existant : Portainer pour la stack, WireGuard pour que les agents restent dans mon réseau isolé.
Ce qu'est Beszel
Beszel c'est un outil de supervision serveur open-source avec une architecture hub-agent. Le hub centralise tout et expose l'interface web. Les agents tournent sur chaque machine à surveiller et remontent les métriques au hub. CPU, RAM, disque, réseau, températures si disponibles — les essentiels, pas plus.
Ce qui m'a convaincu par rapport aux alternatives : la consommation ressources est ridicule. L'agent consomme moins de 10 Mo de RAM en fonctionnement. Sur un VPS à 2 Go, c'est un détail. Sur Netdata, c'était 200 à 300 Mo juste pour l'agent. Et l'interface est réactive — pas de dashboard qui met 5 secondes à charger des dizaines de panels Grafana.
L'autre point fort : la sécurité du modèle de connexion. Comme Portainer, c'est l'agent qui initie la connexion vers le hub, pas l'inverse. Ça change tout pour l'architecture réseau.
La stack Docker via Portainer
Le hub tourne sur mon serveur local principal, derrière Traefik. Je le gère comme toutes mes autres stacks, directement depuis Portainer :
version: "3"
services:
beszel:
image: henrygd/beszel:latest
container_name: beszel
restart: unless-stopped
volumes:
- /opt/beszel/data:/beszel_data
labels:
- "traefik.enable=true"
- "traefik.http.routers.beszel.rule=Host(`beszel.arnaudallouche.fr`)"
- "traefik.http.routers.beszel.entrypoints=websecure"
- "traefik.http.routers.beszel.tls.certresolver=letsencrypt"
- "traefik.http.services.beszel.loadbalancer.server.port=8090"
networks:
default:
external:
name: traefik_web
Premier démarrage, vous créez votre compte admin via l'interface web, et vous récupérez la clé publique SSH du hub dans les paramètres — c'est elle qui authentifie la connexion des agents.
Les agents via WireGuard : rien n'est exposé
Chaque machine à superviser fait tourner un agent Beszel. La subtilité : l'agent écoute par défaut sur le port 45876 en TCP. Comme pour Portainer, je bind ce port uniquement sur l'interface WireGuard de la machine. Depuis Internet, ce port n'existe pas.
Sur chaque serveur à superviser, en stack Portainer :
version: "3"
services:
beszel-agent:
image: henrygd/beszel-agent:latest
container_name: beszel-agent
restart: unless-stopped
network_mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
PORT: 45876
KEY: "ssh-ed25519 AAAA... (clé publique du hub)"
Le network_mode: host est nécessaire pour que l'agent ait accès aux métriques réseau réelles de la machine (pas celles du namespace réseau Docker). Sans ça, les graphes réseau sont faux — j'ai mis un moment à comprendre pourquoi mes VPS semblaient avoir zéro trafic réseau dans le dashboard.
Ensuite, la règle firewall sur l'interface WireGuard — même pattern que pour Portainer :
# Autoriser le port agent uniquement depuis le VPN
ufw allow in on wg0 to any port 45876 proto tcp
Dans l'interface Beszel, quand vous ajoutez un système, vous renseignez l'adresse IP VPN de la machine (10.8.0.x) et le port 45876. Le hub se connecte via WireGuard, la connexion est établie. Depuis Internet, personne ne peut joindre ces agents.
La vue d'ensemble sur toutes les machines
Une fois les agents connectés, le dashboard principal affiche toutes les machines en temps réel. Pour moi : 2 VPS et 2 serveurs locaux, tous visibles sur le même écran.
Ce que je surveille concrètement :
- CPU et RAM sur les VPS — pour détecter un conteneur qui part en boucle ou une fuite mémoire
- Disque — c'est ce qui m'a le plus manqué avant. Beszel affiche le pourcentage d'utilisation et l'évolution. Plus de surprise à 2h du matin
- Réseau — utile pour repérer un trafic anormal, surtout sur les VPS qui ont une limite de bande passante mensuelle
- Conteneurs Docker — Beszel remonte aussi l'état et les métriques des conteneurs individuels si vous montez le socket Docker. Je vois d'un coup d'œil si un conteneur a redémarré ou consomme anormalement
La granularité temporelle va de quelques minutes à plusieurs semaines. Pour un incident, je zoome sur les dernières heures. Pour de la capacité planning, je regarde les tendances sur le mois.
Les alertes Discord
C'est la fonctionnalité qui rend le système réellement utile. Sans alertes, un dashboard c'est un outil passif — vous voyez les problèmes quand vous regardez, pas quand ils se produisent.
Beszel supporte nativement les webhooks. Je l'ai branché sur un canal Discord dédié, ce qui me donne des notifications push sur mon téléphone dès qu'un seuil est franchi.
Configuration dans Settings → Notifications → Add notification :
- Type : Webhook
- URL : l'URL webhook de votre canal Discord (Settings du canal → Intégrations → Webhooks)
Ensuite, par système, vous définissez vos seuils d'alerte :
CPU > 85% pendant 5 minutes → alerte
RAM > 90% → alerte
Disk > 80% → alerte
Statut agent offline → alerte immédiate
Le seuil "agent offline" est celui que j'utilise le plus. Si une machine tombe ou si le réseau WireGuard a un problème, je reçois une notification en moins d'une minute. Avant je le découvrais au hasard.
Un point pratique : les alertes Discord arrivent avec le nom de la machine, la métrique concernée et la valeur actuelle. Pas besoin d'ouvrir le dashboard pour comprendre ce qui se passe — la notification dit "VPS-1 : disque à 87%", c'est directement actionnable.
Ce que ça m'a permis de corriger
Deux semaines après avoir mis Beszel en place, j'ai reçu une alerte RAM à 91% sur le VPS 2. En regardant les métriques des conteneurs, c'était un conteneur Node.js qui grossissait progressivement depuis plusieurs jours — fuite mémoire classique. Sans la supervision, j'aurais découvert le problème quand le VPS aurait commencé à swapper et que les temps de réponse auraient explosé.
J'ai aussi reçu deux alertes disque. La première sur un VPS où les logs Nginx s'accumulaient sans rotation configurée — 40 Go de logs en trois mois. La deuxième sur mon serveur local où les sauvegardes Docker montaient sans limite. Les deux auraient fini par saturer le disque et faire tomber les services.
Pour aller plus loin : le cours vidéo et les fonctions avancées de Beszel
J'ai depuis enregistré un cours complet sur Beszel : installation du hub et des agents, alertes, puis réglages d'expert. Voici la vidéo, et les points du cours qui complètent cet article.
Les deux modes de connexion entre le hub et l'agent
C'est un point qui m'a semblé flou au début, et qui conditionne toute l'architecture :
- Le hub se connecte à l'agent (mode historique). L'agent écoute sur le port
45876et n'accepte que la clé publique du hub, exactement comme une clé SSH autorisée. C'est le mode que j'utilise avec WireGuard : l'agent n'écoute que sur l'adresse VPN, et le hub le joint à travers le tunnel. - L'agent se connecte au hub, avec un jeton. Aucun port à ouvrir sur la machine surveillée : c'est idéal pour une machine derrière une box ou un pare-feu que vous ne contrôlez pas. Avec un jeton universel, les nouveaux agents s'enregistrent même tout seuls auprès du hub, pratique quand on déploie des machines à la chaîne.
Pas de Docker ? Un service suffit
L'agent n'a pas besoin de Docker. Sur une machine sans conteneurs (un routeur sous Linux, un vieux serveur, un Raspberry Pi), le hub fournit une commande d'installation qui pose un binaire et un service systemd. Il existe aussi des versions pour Windows, macOS et FreeBSD.
La santé des disques avec SMART
Beszel lit les données S.M.A.R.T. des disques : secteurs réalloués, erreurs de lecture, température, heures de fonctionnement. Un disque qui commence à lâcher montre souvent des signes plusieurs jours ou semaines avant la panne. Sur des serveurs locaux équipés de disques physiques, c'est une alerte précieuse. Côté Docker, l'agent a besoin d'accéder aux périphériques (/dev/sda, /dev/nvme0) et de la capacité SYS_RAWIO pour lire ces informations.
Les seuils d'alerte bien réglés
En plus de l'alerte d'état (machine injoignable), chaque métrique peut avoir un seuil avec une durée : par exemple, être prévenu quand le processeur dépasse 80 % en moyenne sur 10 minutes, et non au premier pic. C'est ce qui fait la différence entre une alerte utile et une alerte qu'on finit par ignorer. Les notifications partent vers Discord (mon choix), mais aussi Slack, Telegram, Teams, Ntfy, Gotify, l'e-mail ou un webhook générique.
Surveiller le réseau depuis les agents
Les versions récentes permettent aux agents de tester régulièrement un service (ping, TCP, HTTP, DNS) et de mesurer le temps de réponse et les coupures. Utile pour vérifier qu'un serveur local joint bien le hub WireGuard, ou qu'une machine accède à sa base de données distante. Pour la disponibilité des sites vus de l'extérieur, je reste cependant sur Uptime Kuma, plus complet pour cet usage.
Plusieurs utilisateurs, OAuth
Beszel gère plusieurs utilisateurs, et l'administrateur choisit qui voit quel système. La connexion peut passer par OAuth / OpenID Connect : un compte Google, GitHub, ou votre propre fournisseur d'identité (Authentik, Keycloak, Pocket ID).
Sauvegardes et API
Le hub repose sur PocketBase. Deux conséquences pratiques :
- des sauvegardes automatiques configurables dans l'interface d'administration de PocketBase (
/_/), sur le disque local ou vers un stockage compatible S3 ; - toutes les données sont accessibles via l'API REST de PocketBase, pour intégrer les métriques dans vos propres outils ou automatiser l'ajout de systèmes.
Sans sauvegarde du hub, tout l'historique disparaît avec lui. C'est la seule partie de Beszel qui mérite vraiment d'être protégée.
Les bonnes pratiques, en résumé
- Un agent sur chaque machine, même la plus petite : c'est souvent celle qu'on oublie qui tombe.
- Une alerte d'état partout, pour savoir tout de suite quand un serveur ne répond plus.
- Le hub derrière du HTTPS (Traefik dans mon cas).
- Des versions d'images fixées en production plutôt que
latest. - Une sauvegarde du hub, automatique.
Pourquoi cette combinaison fonctionne bien
Ce qui rend le setup cohérent, c'est que les trois outils partagent la même philosophie réseau. WireGuard crée le réseau isolé. Portainer et Beszel font écouter leurs agents uniquement sur ce réseau. Depuis Internet, la surface exposée reste minimale — juste le 443 de Traefik.
Administrativement, tout se gère depuis Portainer : déployer un nouvel agent Beszel sur une nouvelle machine prend deux minutes. Je colle la stack, je renseigne la clé publique du hub, et la machine apparaît dans le dashboard. Même workflow que pour tout le reste de mon infra.
Beszel est en développement actif, l'écosystème est encore jeune. Il manque quelques fonctionnalités qu'on trouve dans des solutions plus matures — pas de gestion fine des droits utilisateurs, les options d'alerte sont basiques comparées à AlertManager. Mais pour superviser une infra personnelle ou une petite équipe, c'est largement suffisant. Et la légèreté reste son principal avantage — je ne sacrifie pas 300 Mo de RAM sur chaque serveur pour avoir un dashboard.