open/gtb
tous les articles

APEX #2 — Les fondations : Docker sur l'APEX sans se faire jeter par l'OPA

13 octobre 2026 · 4 min

#distech-controls,#eclypse-apex,#docker,#mqtt,#mosquitto,#serie-apex

Série ECLYPSE APEX — épisode 2/6 · Précédent : #1 Un automate qui fait tourner Docker, sérieux ?

Vous avez déjà essayé de faire entrer un canapé dans un ascenseur ? Vous tournez, vous basculez, vous retirez les pieds… et ça finit par passer. Créer un conteneur sur un ECLYPSE APEX, c’est exactement ça. Sauf que l’ascenseur s’appelle OPA et qu’il vous répond « request rejected by administrative policy » sans plus d’explication.

Aujourd’hui, on pose les fondations : comment l’APEX gère Docker, les règles à respecter, et notre premier vrai conteneur, Mosquitto. Tout le reste de la série s’appuie dessus.

Ce qu’on a… et ce qu’on n’a pas

Oubliez tout de suite vos réflexes de homelab. Ici, pas de terminal.

Ce qu’on aCe qu’on n’a pas
Menu Conteneurisation dans Eclypse Facilities (images, conteneurs, volumes, réseaux)Pas de SSH, pas de docker exec
L’API REST v2 : /api/rest/v2/services/containerization/...Pas de docker-compose
Des volumes nommés persistantsPas d’endpoint de logs (docker logs)
Un réseau bridge entre conteneursPas de passthrough USB

Chaque conteneur se crée à partir d’un JSON de création, au format de l’API Docker Engine. C’est un peu rugueux au début, mais on s’y fait vite, et c’est finalement très reproductible.

L’OPA, ce videur de boîte de nuit

Un robot videur en lunettes noires, une liste « OPA » à la main, lève la main pour refuser l'entrée d'une zone de conteneurs

Distech a placé un plugin d’autorisation OPA devant le moteur Docker. Son boulot : refuser tout ce qui pourrait mettre l’automate en danger. Après pas mal d’essais-erreurs, voici ce qui passe :

  • ExposedPorts est obligatoire dans le JSON, sinon c’est refusé ;
  • les ports hôtes en 50xxx (et pas tous : 50880 a été refusé chez moi, 50080 accepté) ;
  • des ports internes standards : 1883, 8080, 5432, 6379, 1700, 1880… Un Mosquitto sur 1884 ? Refusé, l’APEX garde certains ports pour lui ;
  • Mounts plutôt que Binds pour les volumes ;
  • "CpusetCpus": "0" dans le HostConfig, ce qui cantonne vos conteneurs à un cœur : la régulation garde les autres.

Retenez cette liste : quand l’OPA vous refuse, c’est quasiment toujours l’un de ces points.

L’ARM64, ou le piège du tag latest

L’APEX tourne sur ARM64. La plupart des images officielles sont multi-arch, mais pas toutes, et parfois pas pour tous les tags. Exemple vécu : chirpstack/chirpstack:latest était x86 uniquement au moment de mes tests, alors que le tag de version fixe passait.

Ma petite astuce pour tester une image sans se prendre la tête : créer un conteneur jetable qui affiche juste son aide.

{
  "Image": "monimage:tag",
  "Cmd": ["--help"],
  "HostConfig": {
    "RestartPolicy": {"Name": "no"},
    "NetworkMode": "bridge"
  }
}

S’il passe en exited, l’image tourne sur l’APEX. S’il reste en restarting, elle n’est pas compatible (ou elle n’aime pas --help, mais c’est plus rare).

Tout-en-un ou multi-conteneurs : l’histoire d’un demi-tour

À gauche, un amas de conteneurs rouillés et ficelés de câbles ; à droite, des conteneurs propres alignés sur un rail DIN

Au début, j’étais persuadé d’avoir trouvé la bonne idée : une seule image custom qui embarquait ChirpStack, PostgreSQL, Redis et Mosquitto. Pas de souci de réseau, pas d’ordre de démarrage, un seul conteneur à déployer. Sur le papier, c’était génial.

Dans la vraie vie, c’était l’enfer. Une mise à jour ? On rebuilde tout. Un service qui plante ? Bonne chance pour savoir lequel. Et l’image pesait un âne mort.

J’ai donc fait demi-tour : un service, un conteneur. C’est plus de JSON à écrire, mais chaque brique vit sa vie, se met à jour seule et se dépanne seule. Toute la suite de la série est construite comme ça.

Les bonnes pratiques qui m’ont sauvé la mise

  • Noms de conteneurs en minuscules. Des noms comme PostgreSQL ou Redis m’ont posé des soucis de résolution entre conteneurs.
  • Communiquer via IP_APEX:port_hôte. C’est le chemin le plus fiable pour qu’un conteneur en joigne un autre.
  • Logs dans un volume. Pas de docker logs ? On redirige la sortie vers un fichier dans un volume, et on le lit avec un FileBrowser ou un nginx monté sur le même volume.
  • Tags de version fixes, toujours.
  • Une table des ports tenue à jour. Croyez-moi, au cinquième conteneur, vous me remercierez.
ServicePort internePort APEX
Node-RED188050080
ChirpStack (web)808050081
Mosquitto188350083
Zigbee2MQTT (web)808050084
nginx (logs)8050089
ChirpStack REST API809050090
FileBrowser (dépannage)8050092
Gateway Bridge LoRaWAN1700/udp50170
Redis637950379
PostgreSQL543250432

Premier conteneur : Mosquitto

Logo MQTT

Mosquitto, c’est le broker MQTT : le hall de gare où tout le monde se croise. Zigbee2MQTT, ChirpStack, Node-RED et Telegraf vont tous y passer, donc c’est logiquement lui qu’on installe en premier.

Vue éclatée d'un automate sur rail DIN : à l'intérieur, une gare « MQTT 1883 » où se croisent des trains de données
  1. Facilities → Conteneurisation → Images → Ajouter : eclipse-mosquitto:2.
  2. Conteneurs → Créer, nom mosquitto, avec ce JSON :
{
  "Image": "eclipse-mosquitto:2",
  "ExposedPorts": { "1883/tcp": {} },
  "Cmd": [
    "sh", "-c",
    "echo 'persistence false\nallow_anonymous true\nconnection_messages true\nlog_type all\nlistener 1883' > /mosquitto/config/mosquitto.conf && mosquitto -c /mosquitto/config/mosquitto.conf"
  ],
  "HostConfig": {
    "CpusetCpus": "0",
    "RestartPolicy": { "Name": "unless-stopped", "MaximumRetryCount": 0 },
    "PortBindings": { "1883/tcp": [{ "HostPort": "50083" }] }
  }
}
  1. Démarrez-le, puis connectez MQTT Explorer depuis votre PC sur IP_APEX:50083.

Remarquez l’astuce : pas de fichier de config à monter, on l’écrit à la volée avec un sh -c. On réutilisera ce principe souvent.

Petite précision qui a son importance : ici le broker accepte les connexions anonymes. C’est parfait sur un banc de test, mais pas sur un site. En production, on active l’authentification et on restreint l’accès réseau.

Et maintenant ?

Les fondations sont coulées : vous savez parler à l’OPA, vérifier une image ARM64, lire des logs sans SSH, et vous avez un broker MQTT qui tourne dans votre automate. Pas mal pour un truc qui vit sur un rail DIN.

Au prochain épisode, on branche un coordinateur Zigbee et on fait obéir un module SONOFF à une GTB pro. Ça va clignoter !

Liens

$ gtb react

Cet article t'a parlé ?

$ gtb comments --tail

Commentaires

// chargement…

open/gtb · MIT · hébergé en France
visiteurs github roadmap messages contact
SYS OK 14/17 outils en ligne uptime — T° baie 21,3 °C