Une image Docker est un modèle immuable, en lecture seule, qui contient un système de fichiers avec tout le nécessaire pour exécuter une application (code, dépendances, configuration). Un conteneur est une instance en cours d’exécution de cette image, avec sa propre couche d’écriture. L’analogie la plus utile vient de la programmation orientée objet : l’image est la classe et le conteneur est l’objet. À partir d’une même image, vous pouvez lancer autant de conteneurs que vous voulez, chacun isolé des autres.
Si vous débutez avec Docker, c’est cette distinction qui évite la plupart des confusions : ce qui se télécharge, ce qui s’exécute, ce qui occupe de l’espace et ce qui se perd à la suppression.
Ce qu’est une image
Une image est construite par couches. Chaque instruction d’un Dockerfile (FROM, RUN, COPY…) produit une couche, et les couches s’empilent : celle du bas est généralement un système de base (Debian, Alpine, Ubuntu), au-dessus viennent les dépendances et en haut le code de votre application. Les couches sont en lecture seule et partagées entre images : si dix images partent de la même base, cette base n’occupe de l’espace disque qu’une seule fois.
Les images s’identifient par un nom et un tag (node:22-alpine, nginx:1.27) et se distribuent via des registres comme Docker Hub.
# Télécharger une image
docker pull nginx:1.27
# Lister les images locales
docker images
# Construire une image à partir du Dockerfile du répertoire courant
docker build -t mon-app:1.0 .
# Supprimer une image (seulement si aucun conteneur ne l’utilise)
docker rmi mon-app:1.0
Ce qu’est un conteneur
Un conteneur est un processus (ou un groupe de processus) qui s’exécute isolé du reste du système, en utilisant l’image comme système de fichiers de base et en ajoutant par-dessus une couche d’écriture. Tout ce que l’application écrit pendant son exécution (journaux, fichiers temporaires, données) va dans cette couche. Quand le conteneur est supprimé, la couche d’écriture disparaît avec lui ; l’image reste intacte.
# Créer et démarrer un conteneur à partir d’une image
docker run -d --name web -p 8080:80 nginx:1.27
# Lister les conteneurs en cours d’exécution (-a inclut les arrêtés)
docker ps
docker ps -a
# Voir les journaux et entrer dans le conteneur
docker logs web
docker exec -it web sh
# Arrêter, redémarrer et supprimer
docker stop web
docker start web
docker rm web
docker run fait deux choses à la fois : il crée le conteneur (docker create) et le démarre (docker start). C’est pourquoi, si vous exécutez docker run trois fois avec la même image, vous obtenez trois conteneurs distincts, pas un seul.
La relation entre les deux, en un tableau
| Image | Conteneur | |
|---|---|---|
| Ce que c’est | Modèle en lecture seule | Instance en cours d’exécution (ou arrêtée) d’une image |
| Se crée avec | docker build, docker pull |
docker run, docker create |
| Se liste avec | docker images |
docker ps -a |
| Se supprime avec | docker rmi |
docker rm |
| Change à l’exécution ? | Non | Oui, dans sa couche d’écriture |
| Combien peut-il y en avoir ? | Un par nom:tag | Autant que vous voulez par image |
Où sont stockées les données : les volumes
Comme la couche d’écriture meurt avec le conteneur, toute donnée qui doit survivre (une base de données, des fichiers envoyés par des utilisateurs) doit vivre à l’extérieur, dans un volume ou dans un répertoire de l’hôte monté dans le conteneur :
# Volume géré par Docker
docker run -d --name db -v donnees-db:/var/lib/postgresql/data postgres:16
# Répertoire de l’hôte (bind mount), pratique en développement
docker run -d --name web -v "$(pwd)/html:/usr/share/nginx/html:ro" -p 8080:80 nginx:1.27
Vous pouvez ainsi supprimer et recréer le conteneur sans perdre les données. La documentation sur les volumes détaille les différences entre les deux options.
Erreurs fréquentes
- Croire que
docker stoplibère l’espace. Un conteneur arrêté existe toujours avec sa couche d’écriture. Pour libérer l’espace, il faut le supprimer avecdocker rm(ou utiliserdocker run --rmpour qu’il se supprime seul à la fin). - Stocker des données dans le conteneur. Ça marche jusqu’à ce que vous le recréiez. Utilisez des volumes dès le début.
- Modifier un conteneur et attendre que l’image change. Ça n’arrive pas. Si une modification doit faire partie de l’image, faites-la dans le
Dockerfileet reconstruisez.docker commitexiste, mais il produit des images non reproductibles et il vaut mieux l’éviter. - Accumuler des images et conteneurs orphelins.
docker system dfmontre ce qu’ils occupent ;docker system prunesupprime les conteneurs arrêtés, les réseaux inutilisés et les images sans tag (il demande confirmation). - Utiliser le tag
latesten production.latestchange avec le temps ; fixez une version précise (node:22.12-alpine) pour que le déploiement soit reproductible.
Conclusion
L’image est le modèle ; le conteneur, l’exécution. Les images se construisent et se téléchargent, les conteneurs se démarrent, s’arrêtent et se suppriment, et les données qui doivent durer vont dans des volumes. Avec ces trois concepts clairs, le reste de Docker (réseaux, Compose, registres) se comprend comme des combinaisons de la même chose.