Docker : ce que tu choisis quand tu choisis un contenant
Docker est un outil qui emballe une application et tout ce dont elle a besoin — code, runtime, bibliothèques, configuration — dans un conteneur. Tu le lances, il tourne. Tu le déplaces, il tourne encore. La promesse est simple, et c'est précisément ce qui la rend dangereuse à avaler sans réfléchir.
Le conteneur, ce n'est pas une machine virtuelle
Une VM embarque un système d'exploitation complet. Un conteneur, non. Il partage le kernel de l'hôte et n'isole que le processus et ses dépendances.Ça change tout. Un conteneur démarre en millisecondes là où une VM met trente secondes. Il consomme quelques mégaoctets là où une VM en réclame des gigas. Tu peux en faire tourner cinquante sur une machine qui en supporterait trois en virtualisation classique.
Le prix à payer est réel. Pas de kernel séparé veut dire pas d'isolation matérielle. Une faille dans le kernel de l'hôte, et tous tes conteneurs sont exposés. Une VM se protège avec l'hyperviseur ; un conteneur se protège avec de la discipline. Ce n'est pas la même monnaie.
L'image, c'est le moule
Une image Docker est un modèle figé. Elle contient les couches de système de fichiers nécessaires à ton application, empilées les unes sur les autres.Tu la construis à partir d'un `Dockerfile`, un fichier texte qui liste les instructions dans l'ordre. Chaque instruction crée une couche. Quand tu lances un conteneur, Docker ajoute une couche inscriptible par-dessus les autres et te laisse travailler dedans.
Ce système de couches, hérité d'UnionFS, fait l'efficacité de Docker. Dix conteneurs lancés depuis la même image partagent la même base en mémoire. Tu ne télécharges pas dix fois ce que tu as déjà.
`docker image inspect` te montre tout : taille, structure des couches, configuration, plateforme cible. La sortie se formate en JSON ou via un template Go, ce qui te permet de scripter proprement.
```bash docker image inspect nginx:1.27-alpine ```
`docker image history` te donne l'inverse : l'historique de construction, couche par couche, avec les instructions qui les ont créées. Quand une image pèse 2 Go et que tu ne comprends pas pourquoi, c'est là que tu regardes.
```bash docker image history nginx:1.27-alpine ```
Distribuer : les registries
Une image ne sert à rien si elle reste sur ta machine. Docker passe par des registries pour les échanger. Le plus connu est Docker Hub, public et gratuit pour les images ouvertes.Pour pousser ou tirer d'un registry privé, tu t'authentifies.
```bash docker login registry.example.com ```
Sans argument, la commande vise `https://registry-1.docker.io/` par défaut. Tu fournis identifiant et mot de passe, Docker stocke un jeton dans `~/.docker/config.json`. Selon la configuration de ta machine, il te faudra `sudo`, ou pas — ça dépend de comment tu as ajouté ton utilisateur au groupe `docker`.
Pour te déconnecter :
```bash docker logout registry.example.com ```
Transporter une image sans réseau
Parfois tu n'as pas de registry accessible. Machine isolée, air gap, réseau pourri. Docker te laisse exporter une image dans un fichier tar.```bash docker image save -o nginx-1.27.tar nginx:1.27-alpine ```
Tu copies le fichier où tu veux, et tu le réimportes de l'autre côté :
```bash docker image load -i nginx-1.27.tar ```
`save` et `load` préservent l'image complète : tags, historique, couches. C'est un transfert fidèle.
`docker image import` fait autre chose. Il crée une image plate à partir d'un tarball de système de fichiers, sans historique, sans couches. Tu l'utilises quand tu pars d'un rootfs existant, pas d'une image Docker. Les deux commandes acceptent l'option `--platform`, utile dès que tu jongles entre AMD64 et ARM64.
La confusion entre `load` et `import` coûte des heures à pas mal de gens. `load` restaure une image Docker. `import` fabrique une image à partir d'un truc qui n'en était pas une.
Une image, plusieurs architectures
Ton laptop est en ARM64. Ton serveur est en AMD64. Tu veux le même nom d'image pour les deux.C'est le rôle des manifest lists. Un manifest décrit une image : ses couches, sa plateforme, ses métadonnées. Une manifest list regroupe plusieurs variantes sous un seul nom. Docker choisit automatiquement la bonne selon la plateforme qui tire.
```bash docker manifest create monapp:1.0 \ --amend monapp:1.0-amd64 \ --amend monapp:1.0-arm64 ```
Puis tu pousses :
```bash docker manifest push monapp:1.0 ```
Le détail de la structure se trouve dans la spécification registry v2. Tu n'as pas besoin de la lire en entier pour t'en servir, mais tu y reviendras le jour où un manifest refusera de se créer sans raison apparente.
Lire les logs d'un conteneur
Un conteneur qui tourne ne dit rien par défaut. `docker logs` récupère ce qu'il a écrit sur stdout et stderr.```bash docker logs -f --timestamps --since 10m mon-conteneur ```
`-f` suit la sortie en direct, comme `tail -f`. `--timestamps` ajoute l'heure. `--since` et `--until` filtrent sur une fenêtre. `-n` limite aux dernières lignes.
```bash docker logs -n 50 mon-conteneur ```
C'est le premier réflexe quand quelque chose ne répond plus. Avant de redémarrer, avant de chercher sur un forum, tu regardes les logs. Neuf fois sur dix, la réponse y est déjà.
Étendre Docker avec des plugins
Docker ne fait pas tout. Les plugins ajoutent des drivers réseau, des drivers de volume, des intégrations avec des systèmes externes.```bash docker plugin create mon-plugin ./mon-plugin-rootfs ```
Tu fournis un rootfs et un fichier `config.json`. L'option `--compress` compresse le contexte en gzip pour faciliter la distribution.
C'est un terrain avancé. La plupart des utilisateurs n'écriront jamais un plugin. Mais savoir que ça existe évite de croire qu'une limite de Docker est une limite de la conteneurisation.
Le dockerd, ce processus que tu oublies
Derrière la commande `docker` que tu tapes, il y a un démon : `dockerd`. Il tourne en arrière-plan, gère le cycle de vie des conteneurs, des images, des réseaux et des volumes.La CLI `docker` n'est qu'un client. Elle traduit tes commandes en appels API vers le démon. C'est le démon qui télécharge les images, démarre les conteneurs, configure les réseaux, surveille les ressources.
Cette séparation a une conséquence pratique. Si le démon tombe, tes conteneurs tombent avec lui, sauf si tu les as configurés avec une politique de redémarrage. Et si tu ne l'as pas fait, tu l'apprends au pire moment.
Ce que Docker résout vraiment
Le problème « ça marche sur ma machine » a coûté des années de productivité à l'industrie. Docker le règle en emballant l'environnement avec l'application.Ton image construite sur ta machine se comporte pareil en staging et en production. Pas parce que Docker est magique, mais parce que rien ne change entre les deux : mêmes couches, même runtime, mêmes bibliothèques.
Ça ouvre la porte à l'automatisation. Un pipeline CI/CD construit une image, la teste, la pousse, la déploie. Chaque étape manipule le même artefact. Pas de dérive de configuration, pas de surprise à la mise en production.
La sécurité, ce n'est pas un module qu'on ajoute
Un conteneur partage le kernel de l'hôte. Une faille dans ce kernel, ou dans le moteur Docker lui-même, peut exposer tous les conteneurs d'une machine.Trois choses comptent plus que le reste. Garder Docker à jour. Faire tourner les conteneurs avec le minimum de privilèges — pas de `--privileged` par confort. Isoler ce qui doit l'être, réseau compris.
Un conteneur lancé en root dans un conteneur qui monte le socket Docker de l'hôte, c'est un accès root à la machine. Ce n'est pas une opinion, c'est une équivalence.
Le choix qui reste ouvert
Docker n'est pas seul. Podman fait tourner des conteneurs sans démon, en rootless par défaut, avec une compatibilité de commandes quasi totale. containerd et CRI-O sont les runtimes que Kubernetes utilise directement. L'Open Container Initiative a standardisé le format d'image, ce qui veut dire que ton image Docker tourne ailleurs sans modification.Ce que Docker apporte, c'est l'écosystème : Docker Hub, Docker Compose, Docker Desktop, une documentation dense et une communauté qui a déjà rencontré ton problème. Ce que ça coûte, c'est un démon central qui tourne en root, une licence Desktop payante pour les grandes entreprises, et une dépendance à un acteur unique pour l'outillage.
Podman te rend le rootless et le sans-démon, mais tu perds une partie du confort et tu découvres que certains outils supposent Docker sans le dire. Kubernetes t'offre l'échelle, mais tu passes d'une commande à un cluster à administrer.
Le bon choix dépend de ce que tu administres. Une machine de développement, un serveur unique, un cluster de production : trois réponses différentes. Ce qui ne change pas, c'est la question à se poser avant de taper `docker run` pour la première fois — pas après avoir découvert que ton conteneur tournait en root depuis six mois.