{"id":4535,"date":"2026-09-18T10:51:07","date_gmt":"2026-09-18T08:51:07","guid":{"rendered":"https:\/\/domo.rem81.com\/?p=4535"},"modified":"2026-09-18T15:48:15","modified_gmt":"2026-09-18T13:48:15","slug":"surveiller-mes-lxc-proxmox-via-mqtt","status":"publish","type":"post","link":"https:\/\/domo.rem81.com\/index.php\/2026\/09\/18\/surveiller-mes-lxc-proxmox-via-mqtt\/","title":{"rendered":"Surveiller mes LXC Proxmox via MQTT"},"content":{"rendered":"\n\n\n\n<h1 class=\"wp-block-heading\">Intro<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Dans mon infrastructure domotique, j&rsquo;ai plusieurs conteneurs LXC qui tournent en continu (Node-RED, ESPHome\/VSCode, Frigate&#8230;). Je voulais un moyen simple de savoir, depuis mon tableau de bord Home Assistant, si un service critique \u00e9tait bien actif, sans avoir \u00e0 me connecter en SSH \u00e0 chaque fois. Voici comment j&rsquo;ai mis \u00e7a en place \u00e0 base de cron, mosquitto_pub et Node-RED.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Le principe<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Chaque LXC surveill\u00e9 ex\u00e9cute un petit script bash toutes les minutes (ou toutes les 5 minutes selon les cas), qui :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>v\u00e9rifie l&rsquo;\u00e9tat du service concern\u00e9 (<code>systemctl is-active<\/code>)<\/li>\n\n\n\n<li>rel\u00e8ve sa version install\u00e9e et compare avec la derni\u00e8re version disponible (registre npm par exemple)<\/li>\n\n\n\n<li>calcule l&rsquo;utilisation CPU et RAM du conteneur<\/li>\n\n\n\n<li>publie le tout en MQTT, avec retenue (<code>-r<\/code>), sous un topic d\u00e9di\u00e9<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Le script (exemple pour Node-RED)<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\nset -u\nPATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin\n\nMQTT_HOST=\"192.168.0.37\"\nMQTT_USER=\"remy\"\nMQTT_PASS=\"********\"\nBASE=\"monitor\/nodered_lxc\"\n\npub() {\n  mosquitto_pub -h \"$MQTT_HOST\" -u \"$MQTT_USER\" -P \"$MQTT_PASS\" -r -t \"$1\" -m \"$2\"\n}\n\n# ... d\u00e9tection du service, version, CPU, RAM ...\n\npub \"$BASE\/status\"   \"$RUNNING\"\npub \"$BASE\/version\"  \"$CURRENT\"\npub \"$BASE\/latest\"   \"$LATEST\"\npub \"$BASE\/cpu_pct\"  \"$CPU_PCT\"\npub \"$BASE\/mem_pct\"  \"$MEM_PCT\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Il est d\u00e9clench\u00e9 par une t\u00e2che cron root dans le conteneur :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>*\/1 * * * * \/usr\/local\/bin\/nodered_version_mqtt.sh &gt;\/dev\/null 2&gt;&amp;1<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Flux des informations<\/h1>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"888\" src=\"https:\/\/domo.rem81.com\/wp-content\/uploads\/2026\/09\/chaine_publication_mqtt_monitor_v2-1024x888.png\" alt=\"\" class=\"wp-image-4542\" srcset=\"https:\/\/domo.rem81.com\/wp-content\/uploads\/2026\/09\/chaine_publication_mqtt_monitor_v2-1024x888.png 1024w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2026\/09\/chaine_publication_mqtt_monitor_v2-300x260.png 300w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2026\/09\/chaine_publication_mqtt_monitor_v2-768x666.png 768w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2026\/09\/chaine_publication_mqtt_monitor_v2-1536x1333.png 1536w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2026\/09\/chaine_publication_mqtt_monitor_v2-2048x1777.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Le cron d\u00e9clenche le script qui publie sur le broker MQTT de Home Assistant ; Node-RED relaie ensuite ces topics vers le broker central, d\u2019o\u00f9 ils sont lus par les capteurs du dashboard.<\/em><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Le pont Node-RED<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">J&rsquo;ai un broker MQTT d\u00e9di\u00e9 \u00e0 Home Assistant (192.168.0.37) et un broker central (192.168.0.204) qui agr\u00e8ge plusieurs sources. Un flow Node-RED (\u00ab\u00a0Bridge MQTT Prefix\u00a0\u00bb) \u00e9coute <code>monitor\/#<\/code> sur le broker HA et republie tel quel vers le broker central, ce qui me permet de centraliser toutes mes m\u00e9triques d&rsquo;infrastructure \u00e0 un seul endroit.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">C\u00f4t\u00e9 Home Assistant<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Des capteurs MQTT lisent simplement ces topics :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mqtt:\n  sensor:\n    - name: \"Node-RED LXC Version\"\n      unique_id: nodered_lxc_version\n      state_topic: \"monitor\/nodered_lxc\/version\"\n      icon: mdi:package-variant\n\n    - name: \"Node-RED LXC Version la plus r\u00e9cente\"\n      unique_id: nodered_lxc_latest\n      state_topic: \"monitor\/nodered_lxc\/latest\"\n      icon: mdi:cloud-download\n\n    - name: \"Node-RED LXC CPU\"\n      unique_id: nodered_lxc_cpu_pct\n      state_topic: \"monitor\/nodered_lxc\/cpu_pct\"\n      unit_of_measurement: \"%\"\n      state_class: measurement\n      device_class: power_factor\n      icon: mdi:cpu-64-bit\n\n    - name: \"Node-RED LXC M\u00e9moire\"\n      unique_id: nodered_lxc_mem_pct\n      state_topic: \"monitor\/nodered_lxc\/mem_pct\"\n      unit_of_measurement: \"%\"\n      state_class: measurement\n      icon: mdi:memory\n\n  binary_sensor:\n    - name: \"Node-RED LXC En cours d'ex\u00e9cution\"\n      unique_id: nodered_lxc_running\n      state_topic: \"monitor\/nodered_lxc\/status\"\n      payload_on: \"running\"\n      payload_off: \"stopped\"\n      device_class: running\n      \ntemplate:\n  - binary_sensor:\n      - name: \"Node-RED LXC Mise \u00e0 jour disponible\"\n        unique_id: nodered_lxc_update\n        device_class: update\n        state: >\n          {% set cur = states('sensor.node_red_lxc_version') %}\n          {% set lat = states('sensor.node_red_lxc_version_la_plus_recente') %}\n          {{ cur not in &#091;'unknown','unavailable','none',''] and\n             lat not in &#091;'unknown','unavailable','none',''] and\n             cur != lat }}      <\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">R\u00e9sultat : un petit tableau de bord qui me montre en un coup d&rsquo;\u0153il la sant\u00e9 de chaque LXC surveill\u00e9.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Le binary_sensor indique si une une mise \u00e0 jour est \u00e0 r\u00e9aliser.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Pi\u00e8ge rencontr\u00e9 : les messages retained et les scripts orphelins<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Un de mes LXC (\u00e0 l&rsquo;origine d\u00e9di\u00e9 \u00e0 ESPHome) a depuis \u00e9t\u00e9 reconverti en serveur VSCode. Le script <code>esphome_version_mqtt.sh<\/code> continuait pourtant de tourner dessus, cherchant un service <code>esphome<\/code> qui n&rsquo;existait plus \u2014 d&rsquo;o\u00f9 un statut \u00ab\u00a0stopped\u00a0\u00bb fant\u00f4me affich\u00e9 en permanence dans mon dashboard.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c0 retenir : quand on republie avec l&rsquo;option <code>-r<\/code> (retained), le broker garde le dernier message m\u00eame si plus personne ne le republie. Penser \u00e0 purger ces topics explicitement apr\u00e8s suppression d&rsquo;un script :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>for t in version latest cpu_pct mem_pct status; do\n  mosquitto_pub -h 192.168.0.37 -u remy -P \"********\" -t \"monitor\/esphome_lxc\/$t\" -r -n\ndone<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">(Le flag <code>-n<\/code> publie un message vide, ce qui supprime le retained c\u00f4t\u00e9 broker.)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Article r\u00e9dig\u00e9 avec l&rsquo;assistance de Claude AI (Anthropic) \u00e0 partir de mes donn\u00e9es et retours d&rsquo;exp\u00e9rience.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intro Dans mon infrastructure domotique, j&rsquo;ai plusieurs conteneurs LXC qui tournent en continu (Node-RED, ESPHome\/VSCode, Frigate&#8230;). Je voulais un moyen simple de savoir, depuis mon tableau de bord Home Assistant, &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,68],"tags":[59,66],"class_list":["post-4535","post","type-post","status-publish","format-standard","hentry","category-homeassistant","category-proxmox","tag-mqtt","tag-nodered"],"_links":{"self":[{"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/posts\/4535","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/comments?post=4535"}],"version-history":[{"count":8,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/posts\/4535\/revisions"}],"predecessor-version":[{"id":4546,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/posts\/4535\/revisions\/4546"}],"wp:attachment":[{"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/media?parent=4535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/categories?post=4535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/tags?post=4535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}