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 a | Ce 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 persistants | Pas d’endpoint de logs (docker logs) |
| Un réseau bridge entre conteneurs | Pas 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

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 :
ExposedPortsest 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 ;
Mountsplutôt queBindspour les volumes ;"CpusetCpus": "0"dans leHostConfig, 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

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
PostgreSQLouRedism’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.
| Service | Port interne | Port APEX |
|---|---|---|
| Node-RED | 1880 | 50080 |
| ChirpStack (web) | 8080 | 50081 |
| Mosquitto | 1883 | 50083 |
| Zigbee2MQTT (web) | 8080 | 50084 |
| nginx (logs) | 80 | 50089 |
| ChirpStack REST API | 8090 | 50090 |
| FileBrowser (dépannage) | 80 | 50092 |
| Gateway Bridge LoRaWAN | 1700/udp | 50170 |
| Redis | 6379 | 50379 |
| PostgreSQL | 5432 | 50432 |
Premier conteneur : Mosquitto

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.

- Facilities → Conteneurisation → Images → Ajouter :
eclipse-mosquitto: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" }] }
}
} - 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
- Fiche produit ECLYPSE APEX — Distech Controls
- Endpoints utiles de l’API REST v2 :
/services/platform,/services/containerization/containers,/images,/volumes,/networks - Mosquitto et MQTT Explorer
$ gtb react
Cet article t'a parlé ?
$ gtb comments --tail
Commentaires
// chargement…