Passer de quelques conteneurs lancés à la main à un déploiement Docker reproductible change complètement la vie d’une équipe technique. Tout se joue souvent autour de quelques commandes bien maîtrisées : docker run pour créer et lancer un conteneur, docker start pour relancer ce qui existe déjà, docker compose pour orchestrer un ensemble de services. Entre les mains d’un développeur ou d’un responsable IT/OT, ces commandes deviennent un levier concret pour stabiliser un environnement, fiabiliser un déploiement et raccourcir les délais de mise en production.
Sur le terrain, notamment dans les projets IoT et edge, les mêmes questions reviennent : quelle cmd docker utiliser en phase de prototypage, laquelle en production, comment éviter les conteneurs orphelins ou les volumes oubliés. Derrière ces interrogations se cache une grille de lecture simple : docker run sert à poser le « moule » d’exécution d’une image, docker start sert à la réutiliser, docker compose sert à décrire et automatiser tout un empilement de services. L’objectif n’est pas de connaître toutes les options par cœur, mais de comprendre comment les combiner pour que l’infrastructure reste lisible, même un lundi matin avec un service en panne.
Ce texte propose une lecture concrète de ces commandes, avec un fil rouge : une petite équipe qui déploie une passerelle edge pour remonter des données de capteurs vers le cloud. À chaque étape, les commandes Docker seront reliées à des situations de travail réelles : diagnostic sur site, montée de version, rollback, intégration avec des services web ou des bus de messages. L’idée est simple : que chaque lecteur puisse ressortir avec quelques réflexes opérationnels, transposables aussi bien sur un laptop de développement que sur un serveur hébergé chez un acteur comme Scaleway ou OVH.
En bref
- docker run sert à créer et lancer un nouveau conteneur à partir d’une image, avec sa configuration complète (ports, volumes, variables d’environnement).
- docker start relance un conteneur déjà créé, sans redéfinir sa configuration, ce qui évite des erreurs de copie de commande.
- docker compose gère l’orchestration locale de plusieurs services décrits dans un fichier YAML, utile dès que l’application dépasse un seul conteneur.
- Pour un déploiement reproductible, il vaut mieux figer la configuration dans un fichier compose que dépendre de l’historique du terminal.
- Dans les environnements IoT et edge, bien penser la gestion des conteneurs dès le début évite des arrêts de production coûteux.
docker run : comprendre la commande qui crée et lance les conteneurs
Au centre de la plupart des tutoriels se trouve la commande docker run. Elle paraît simple, presque anodine, pourtant c’est souvent là que se jouent les bonnes ou mauvaises habitudes. Cette commande ne se contente pas de « lancer » quelque chose : elle crée d’abord un conteneur à partir d’une des images docker disponibles, puis démarre ce conteneur avec la configuration passée en paramètres. Autrement dit, chaque docker run ajoute un nouvel objet à la pile que le moteur Docker devra ensuite gérer.
Pour l’équipe fictive qui pilote une passerelle IoT en atelier, le premier réflexe est souvent le suivant :
docker run -it --rm alpine sh
Cette ligne sert de couteau suisse pour tester le réseau, inspecter un volume, ou vérifier qu’un DNS répond. Quelques options méritent d’être disséquées. L’option -it combine le mode interactif et l’allocation d’un pseudo-terminal, ce qui facilite les tests en ligne de commande. Le –rm indique au moteur de supprimer automatiquement le conteneur une fois la session terminée, pratique pour éviter l’accumulation d’objets inutiles.
Quand il s’agit d’une application réelle, la commande se complexifie vite. Prenons un exemple plus proche d’un cas de production IoT :
docker run -d --name edge-mqtt -p 1883:1883 -v /data/mqtt:/var/lib/mqtt -e LOG_LEVEL=info eclipse-mosquitto
Cette fois, le conteneur tourne en arrière-plan grâce au -d, porte un nom explicite avec –name, expose le port 1883 vers l’extérieur, mappe un volume de données et définit une variable d’environnement. Tout ce qui est écrit ici devient la « carte d’identité » du conteneur. Une erreur dans la commande, et la session suivante héritera d’un comportement bancal, parfois difficile à diagnostiquer à distance.
Une première position nette s’impose : pour tout ce qui touche au long terme (base de données, broker MQTT, API métier), multiplier les docker run manuels avec des options tapées à la main constitue un pari risqué. Sur un laptop personnel, cela peut passer. Sur un serveur d’atelier ou une gateway en bord de ligne, cela se paie en heures de recherche de cause lors du premier incident sérieux.
Dans les projets qui mêlent IoT, web et intégrations industrielles, la tension entre vitesse et traçabilité est palpable. Un développeur veut tester vite, un responsable d’exploitation demande un historique, un RSSI met l’accent sur la sécurité. docker run reste un outil idéal pour explorer, mesurer, voir rapidement le comportement d’une nouvelle image. Mais dès que la configuration commence à accumuler des paramètres, déplacer cette logique dans un fichier de configuration devient un gain tangible.
Un autre point de vigilance concerne les volumes. Une commande comme :
docker run -d --name db-test -v db-data:/var/lib/postgresql/data postgres:15
crée un volume nommé db-data qui survivra à l’arrêt ou à la suppression du conteneur. Sans politique claire de nettoyage, ces volumes s’accumulent, occupent de l’espace disque et brouillent la lecture de la plateforme. Sur un serveur dédié à l’edge computing évoqué dans cet article, il n’est pas rare de retrouver plusieurs dizaines de volumes vestiges de tests anciens, créés au fil des cmd docker successives.
Pour structurer ces usages, plusieurs équipes documentent quelques modèles de docker run validés, stockés dans un dépôt Git, avec des commentaires et des exemples d’options. Cette documentation fait le lien avec des sujets plus larges comme l’architecture IoT ou l’intégration de briques logicielles, à l’image de ce qui est détaillé sur les intégrations entre IoT et informatique classique. Le message sous-jacent reste le même : docker run doit être vu comme un outil d’exploration cadré, pas comme un mode de déploiement pérenne.
En résumé, docker run brille pour créer un conteneur sur mesure, mais chaque commande engage une dette de configuration qu’il faut accepter ou documenter. Ceux qui anticipent ce point gagnent du temps lors de la phase de montée en charge.

docker start et les commandes associées : gérer le cycle de vie sans casser la configuration
Une fois les premiers conteneurs créés, le réflexe naturel devrait être de les réutiliser. C’est exactement le rôle de docker start : reprendre un conteneur existant, avec sa configuration d’origine, et le remettre en route. À l’inverse de docker run, cette commande ne crée rien de nouveau, ne touche pas aux volumes, ne modifie pas les ports exposés. Elle se contente de ramener en mémoire un objet déjà défini dans le moteur Docker.
Dans la petite entreprise qui déploie des passerelles IoT pour suivre la consommation énergétique d’une usine, ce détail change la vie. Pendant la mise en service, un technicien coupe et relance l’alimentation de la gateway, les services se relancent en automatique, mais un jour un conteneur reste éteint. Sur le support distant, la commande réflexe ressemble à :
docker ps -a
puis :
docker start edge-mqtt
Le conteneur reprend son fonctionnement, sans risque d’erreur sur les ports ou les volumes, ce qui limite les impacts sur les autres services en place. Cela peut paraître trivial, pourtant beaucoup continuent de taper des docker run approximatifs au lieu de miser sur docker start et docker stop pour la vie quotidienne des services.
Une observation revient souvent chez les clients industriels : plus la commande tapée est longue, plus le risque d’erreur augmente. Entre un copier-coller partiel, une option oubliée ou un port déjà utilisé, chaque variation crée une dérive. Sur une ligne de production, cette dérive peut se traduire par une perte de données ou un arrêt d’alarme. Utiliser docker start signifie capitaliser sur une configuration déjà testée, approuvée, restée stable.
Autour de cette commande orbitent plusieurs autres gestes utiles :
- docker restart pour redémarrer rapidement un conteneur, pratique après un changement de configuration interne au service.
- docker stop pour arrêter proprement, en laissant au processus le temps de se fermer.
- docker rm pour supprimer un conteneur devenu inutile, afin de garder un environnement lisible.
Là aussi, la frontière entre environnement de dev et environnement de production joue un rôle clé. Sur un laptop, saturer la sortie de docker ps -a avec une vingtaine de conteneurs morts n’est qu’un irritant visuel. Sur une passerelle déployée dans une armoire électrique, ce désordre complique les diagnostics, surtout quand les équipes se relaient ou que la maintenance est partagée avec un intégrateur externe.
Un exemple concret illustre ce point. Sur un site logistique équipé de capteurs de température, l’API de supervision tourne dans un conteneur nommé edge-api. Après une mise à jour de l’hyperviseur, l’API ne répond plus. Premier réflexe de l’équipe sur place : lancer un nouveau docker run avec une image récente, pensant « remettre à zéro » la situation. Résultat, deux conteneurs edge-api cohabitent avec des ports différents, certains scripts internes continuent de pointer vers l’ancien, et les écarts de mesure se multiplient. Une séquence simple docker start sur le bon conteneur, combinée à des logs inspectés calmement, aurait évité cette dérive.
Autre point rarement abordé : la relation entre docker start et les politiques de redémarrage automatique. Une commande docker run enrichie de --restart=unless-stopped ou --restart=always permet d’ancrer dans la configuration le comportement attendu en cas de reboot. À partir de là, le recours à docker start devrait devenir exceptionnel. Si un conteneur ne repart pas alors que la politique l’y invite, la question n’est plus « comment le démarrer », mais « pourquoi a-t-il échoué ». Ce changement de posture amène un diagnostic plus rigoureux.
Dans les organisations où les équipes IT et OT se croisent sans toujours parler le même langage, clarifier ces usages de base évite des tensions inutiles. Lorsqu’un automaticien découvre que l’arrêt de son SCADA vient d’un docker run hasardeux sur un serveur partagé, la confiance dans l’outillage recule. À l’inverse, une discipline simple autour de docker start et des politiques de redémarrage donne une impression de solidité, qui compte énormément lorsque l’on discute d’orchestration plus avancée ou de migration vers le cloud.
En un mot, docker start sert à respecter ce qui a été défini une fois pour toutes. Dans un environnement où les arrêts de production se comptent en milliers d’euros, cette forme de respect de la configuration initiale tient presque du réflexe de sécurité.
Une ressource vidéo claire sur ces commandes de base aide souvent à aligner l’équipe, notamment quand des profils moins familiers avec la ligne de commande rejoignent le projet.
docker compose et orchestration locale : décrire plutôt que mémoriser
Dès que l’application dépasse un seul conteneur, continuer uniquement avec docker run revient à jongler avec des assiettes en porcelaine sur un sol en béton. Une API, une base de données, un broker MQTT, un frontal web, parfois un agent de supervision ou un collecteur de logs : tout cela finit par dépendre les uns des autres. À ce stade, l’outil qui change la donne est docker compose, pensé précisément pour cet empilement de services.
Concrètement, docker compose s’appuie sur un fichier YAML, souvent nommé docker-compose.yml, qui décrit de manière déclarative les services, leurs ports, leurs volumes, leurs variables d’environnement, et leurs liens. L’avantage principal tient dans cette phrase : la configuration sort de l’historique du terminal pour entrer dans un fichier versionné, relu, commenté. Pour une équipe IoT qui déploie la même architecture sur dix sites différents, ce changement est loin d’être cosmétique.
Un exemple minimal mais utile pour une passerelle edge pourrait être :
version: "3.9"
services:
mqtt:
image: eclipse-mosquitto
ports:
- "1883:1883"
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
api:
image: registry.local/edge-api:1.4.2
environment:
- MQTT_HOST=mqtt
depends_on:
- mqtt
Une fois ce fichier en place, un simple :
docker compose up -d
suffit pour monter l’ensemble des services. Plus besoin de retenir la longue litanie d’options, ni de vérifier si l’ordre de démarrage respecte les dépendances. Tout est décrit et orchestré par l’outil. C’est là que le mot orchestration prend un sens concret, même si l’on reste dans un périmètre local, loin de Kubernetes.
Ce choix de passer par un fichier compose emporte plusieurs conséquences positives :
D’abord, la reproductibilité. L’équipe peut déposer ce fichier dans un dépôt Git, l’associer à des issues, l’annoter, le relire en comité d’architecture. Sur un nouveau site, il suffit de cloner le dépôt, adapter quelques variables, lancer la commande et retrouver le même empilement de services. Cela rejoint directement la logique d’outillage décrite dans certains retours sur les plateformes en ligne pour développeurs, à l’image des analyses disponibles sur l’outillage Replit.
Ensuite, la lisibilité. Un responsable OT qui ne maîtrise pas la ligne de commande Docker peut tout de même ouvrir le YAML, comprendre quels services tournent sur la passerelle, quels ports sont utilisés, où sont stockées les données. Cette transparence apaise souvent des discussions sur la cybersécurité ou sur les procédures de reprise d’activité.
Enfin, la facilité de mise à jour. Changer la version d’une image se résume à modifier une ligne, puis relancer un docker compose pull suivi de docker compose up -d. Cette clarté facilite la préparation de fenêtres de maintenance, ou encore la mise en place d’une procédure de rollback en cas de comportement inattendu.
Une réserve cependant : tout écrire dans un fichier compose ne dispense pas de réfléchir à la segmentation des services et aux risques de dépendance forte. Voir un seul fichier composer plus d’une dizaine de services critiques peut tenter certains architectes, mais cette approche complique ensuite les mises à jour et les diagnostics. Parfois, découper en deux ou trois stacks distinctes, chacune avec son propre fichier compose, offre un meilleur compromis entre isolation et simplicité.
Au passage, docker compose introduit une nuance importante dans la gestion des conteneurs : ce n’est plus chaque conteneur qui est manipulé individuellement, mais un ensemble de services. Un docker compose stop ou un docker compose restart s’applique à tout un groupe cohérent. Pour les équipes en astreinte, cette différence peut sauver quelques heures de recherche, à condition d’être clairement expliquée et documentée.
Pour qui travaille sur des architectures distribuées, proches de l’edge computing, docker compose devient vite le point de passage obligé entre le prototype et la pré-production. Ceux qui s’en tiennent à des scripts shell à base de docker run finissent souvent par réinventer compose avec moins de garde-fous et plus de pièges.
En pratique, la meilleure façon d’ancrer docker compose dans une équipe reste de partir d’un cas concret, de le mettre dans Git, puis d’outiller quelques commandes de routine pour masquer la partie la plus répétitive.
Une démonstration vidéo, axée sur le déploiement d’une stack complète, aide souvent à convaincre les plus sceptiques de passer à une description déclarative.
Comparer docker run, docker start et docker compose : usages, forces et limites
Une fois les trois commandes posées, la question revient : quand utiliser quoi, sans se perdre dans les détails. Plutôt qu’une énième liste théorique, un tableau comparatif centré sur l’usage réel permet de fixer les idées.
| Commande | Rôle principal | Contexte idéal | Risques en cas de mauvais usage |
|---|---|---|---|
| docker run | Créer et lancer un nouveau conteneur à partir d’une image | Tests rapides, exploration d’une image, prototypes locaux | Accumulation de conteneurs, configurations incohérentes, difficultés de reproduction |
| docker start | Relancer un conteneur existant sans modifier sa configuration | Exploitation quotidienne, redémarrage après incident, scripts simples | Tendance à masquer un problème plus profond si l’échec de démarrage n’est pas analysé |
| docker compose | Orchestration locale de plusieurs services décrits dans un fichier YAML | Stacks multi-services, déploiement sur plusieurs sites, pré-production | Fichiers trop monolithiques, dépendances complexes, difficultés de mise à jour fine |
Avec cette vue, une première règle pratique se dégage : réserver docker run au terrain de jeu, confier docker compose aux architectures un peu sérieuses, et laisser docker start gérer la vie courante. Ceux qui mélangent tout finissent tôt ou tard par passer plus de temps à comprendre leurs propres scripts qu’à faire évoluer leurs produits.
Dans les projets IoT, les équipes qui réussissent ce virage adoptent souvent une organisation graduée. En local, les développeurs utilisent docker run pour explorer rapidement une nouvelle image docker, vérifier une version particulière de base de données, ou valider un comportement de logging. Une fois un service stabilisé, la configuration bascule dans un compose, qui sert de référence partagée. En exploitation, les techniciens n’ont plus besoin que de quelques commandes : docker compose ps, docker compose logs, docker compose restart.
Autre point de vue assumé : introduire docker compose trop tard coûte cher. Quand un système de production tourne déjà avec cinq ou six conteneurs invoqués par des scripts maison, la migration vers un fichier compose a tendance à traîner. À l’inverse, démarrer un nouveau projet avec un compose minimal n’empêche pas les tests ad hoc, mais fixe d’emblée une structure claire pour le déploiement.
Au passage, ces différents niveaux de commande façonnent aussi la manière de documenter un projet. Une documentation qui se contente d’empiler des exemples de cmd docker sans expliquer la logique derrière conduit rarement à un transfert de compétences solide. Expliquer pourquoi tel service reste géré par docker run alors que tel autre passe par compose donne un signal fort sur la maturité de l’architecture.
Enfin, la question du choix des images mérite une mention. À force de tirer latest dans tous les sens, beaucoup d’équipes découvrent que deux gateways IoT censées être identiques ne se comportent pas pareil. Figer des versions précises dans le fichier compose, tester les mises à jour en environnement de pré-production puis documenter les résultats offre un socle plus solide. Les plateformes d’agrégation de données et d’analytique n’aiment pas les comportements aléatoires, et Docker n’échappe pas à cette règle.
Pour qui réfléchit en termes de ROI, tout cela peut sembler des détails d’exécution. Pourtant, c’est souvent là que se joue la différence entre un prototype sympathique et un système qui tient plusieurs hivers dans une usine.
De la théorie au terrain : scénario complet de déploiement Docker dans un projet IoT
Pour rendre ces commandes moins abstraites, autant suivre un scénario de bout en bout. Imaginons une PME qui veut suivre la consommation énergétique de ses machines-outils. Un petit boîtier edge remonte les compteurs, les agrège, puis envoie les données vers un backend web. Le tout tourne sur un mini PC industriel, posé dans une armoire électrique, relié à quelques réseaux OT parfois capricieux.
Au début du projet, l’équipe technique assemble les briques côté bureau. Un développeur extrait un outil de mesure dans un conteneur Alpine avec docker run pour vérifier la latence réseau. Un autre lance un docker run MongoDB pour stocker des échantillons, juste le temps de tester un algorithme de détection de dérive. Ces usages rapides ne posent pas de problème tant qu’ils restent dans le champ du prototype.
Très vite, l’architecture cible se dessine : un broker MQTT, une base de données timeseries, une petite API, un frontal web pour les tableaux de bord, un agent pour remonter l’état de la passerelle. Plutôt que de multiplier les scripts maison, l’équipe écrit un fichier docker compose qui décrit ces services, leurs ports et leurs volumes. Ce fichier devient la pièce maîtresse du dépôt Git, relu en comité de conception, relié à des issues spécifiques.
Sur le premier site pilote, un technicien arrive avec une passerelle préconfigurée. Après une vérification réseau minimale, il exécute simplement :
git pull
docker compose pull
docker compose up -d
En quelques secondes, les conteneurs montent, les journaux confirment les connexions, les premiers points remontent. Pour les tests ponctuels, le même technicien garde dans sa poche quelques modèles de docker run pour lancer un conteneur de diagnostic réseau, inspecter un volume, ou vérifier l’heure système.
Quelques semaines plus tard, une mise à jour de l’algorithme de détection de dérive est prête. Elle repose sur une nouvelle version de l’API edge. Plutôt que de jouer avec des options en ligne de commande, l’équipe met à jour la version de l’image dans le fichier compose, teste la nouvelle stack sur un banc d’essai, puis planifie la mise à jour sur les sites clients. Le jour venu, la procédure tient en quatre lignes, documentées et testées :
docker compose pull api
docker compose up -d api
docker compose logs -f api
Au cas où un comportement étrange serait observé, un simple retour sur la version précédente reste possible, toujours via le même fichier compose. Pas de surprise cachée dans l’historique du shell.
Dans ce scénario, docker start reste rare en exploitation normale. Les politiques de redémarrage automatique gèrent la plupart des cas après un reboot ou une coupure de courant. Quand un conteneur refuse de repartir, la question n’est pas « comment taper la commande », mais « quelle cause racine explique ce refus ». Une fois la cause identifiée, les ajustements se font dans la configuration partagée, pas dans un coin de terminal sur un site isolé.
Tout au long du projet, les commandes docker run, docker start et docker compose restent présentes, mais leur rôle est clair. Le premier sert de tournevis pour les tests et les diagnostics. Le second s’occupe des redémarrages maîtrisés. Le troisième pilote la stack complète, documentée et versionnée. Ce partage des tâches limite les ambiguïtés et simplifie la montée en compétence des nouveaux arrivants.
D’ailleurs, ce type d’organisation s’insère bien dans une approche plus globale de l’architecture IoT qui cherche à relier l’edge, le cloud et les systèmes métier. Ceux qui ont déjà posé une architecture claire, avec des flux soignés et des contrats d’API lisibles, voient très vite comment Docker vient soutenir cette structure plutôt que de la compliquer. Les autres découvrent parfois que l’outil rend visibles des fragilités sous-jacentes.
Au final, ce scénario illustre une conviction assez simple : bien utiliser ces trois commandes ne rend pas un système infaillible, mais réduit nettement la part de surprise lors des incidents. Et dans un atelier bruyant, à 6 h un lundi, cette réduction de surprise vaut largement quelques heures passées à réfléchir devant un fichier compose.
Quand utiliser docker run plutôt que docker compose pour un nouveau service ?
docker run reste adapté pour explorer une nouvelle image, tester rapidement une configuration, vérifier un comportement réseau ou système. Dès que le service est amené à s’intégrer dans une architecture plus large, ou à être déployé sur plusieurs machines, il devient plus pertinent de décrire sa configuration dans un fichier docker compose afin de gagner en reproductibilité et en lisibilité.
Pourquoi docker start est préférable à un nouveau docker run pour relancer un service ?
docker start réutilise la configuration du conteneur existant : ports, volumes, variables d’environnement restent identiques. Lancer un nouveau docker run pour un service déjà en place risque de créer un second conteneur avec des différences subtiles, ce qui complique les diagnostics et peut provoquer des conflits de ports ou des pertes de données.
docker compose peut-il remplacer complètement docker run dans un projet ?
Pour les services durables et intégrés dans une architecture, docker compose peut effectivement remplacer l’usage courant de docker run. En revanche, pour les tests rapides, le dépannage sur site ou l’exploration d’images, docker run garde toute sa place comme outil de diagnostic ponctuel. Les deux approches se complètent plutôt qu’elles ne s’excluent.
Comment éviter d’accumuler des conteneurs et volumes inutiles avec Docker ?
Un nettoyage régulier fait partie des bonnes pratiques : docker ps -a pour identifier les conteneurs arrêtés, docker rm pour supprimer ceux qui ne servent plus, docker volume ls puis docker volume rm pour les volumes orphelins. Utiliser l’option –rm sur les docker run de test limite la création d’objets persistants. S’appuyer sur docker compose clarifie aussi les volumes réellement utilisés.
Quelle commande Docker privilégier sur une passerelle IoT en production ?
Sur une passerelle en production, la majorité des opérations devrait passer par docker compose pour gérer l’ensemble des services, complété par quelques docker start ou docker restart bien identifiés. docker run doit rester réservé à des interventions de diagnostic temporaire, afin de ne pas injecter de nouvelles configurations non tracées dans l’environnement de production.