infra / docker
Gestion des images (build/tag/push/pull)
Explication
Ce que vous allez apprendre
- Comprendre le rôle d'un registre d'images et la convention de nommage d'un tag
- Comprendre pourquoi un tag n'est qu'un alias léger, sans duplication de données
- Comprendre pourquoi
latestest dangereux à utiliser sans discipline en production - Publier et récupérer une image avec
docker push/docker pullaprès authentification - Transférer une image sans registre avec
docker save/docker load(environnement air-gapped)
Dans quel contexte ?
Une équipe DevOps doit déployer la version 2.3.1 de son API sur un serveur de production qui n'a jamais accès direct à Internet (environnement air-gapped, fréquent en contexte bancaire ou industriel). Impossible de faire un simple docker pull depuis ce serveur. La solution : construire et tagger l'image sur une machine avec accès au registre, l'exporter avec docker save -o mon-api.tar, la transférer physiquement ou via un canal sécurisé, puis la charger sur le serveur cible avec docker load.
Construire une image ne suffit pas
Une image construite localement (leçon précédente) ne vit que sur la machine où elle a été créée. Pour la partager avec une équipe ou la déployer sur un serveur, il faut un mécanisme de distribution : c'est le rôle du registre (registry), un serveur qui stocke des images et permet de les récupérer par leur nom, comme un dépôt Git stocke du code.
| Commande | Effet |
|---|---|
docker tag | Crée un alias vers la même image (aucune copie) |
docker push / pull | Transfère depuis/vers un registre distant |
docker save / load | Exporte/importe une image en fichier .tar local |
Prérequis
Cette leçon suppose que tu sais déjà construire une image avec docker build (leçon précédente sur le Dockerfile).
Comprendre le "tag"
Une image seule ne suffit pas à s'y retrouver : on a besoin d'identifier précisément quelle version on manipule. C'est le rôle du tag, qui suit une convention à trois parties : [registre/][espace de noms/]dépôt[:tag]. Il faut bien comprendre qu'un tag n'est pas une copie de l'image : c'est juste une étiquette, un alias qui pointe vers un contenu déjà existant. On peut donc coller plusieurs tags différents sur la même image sans dupliquer le moindre octet sur le disque.
Pourquoi éviter "latest" en production
latest est simplement le tag par défaut si on n'en précise pas — ce n'est pas une notion magique de "dernière version stable". Deux images différentes peuvent toutes les deux s'appeler latest à des moments différents, ce qui rend impossible de savoir avec certitude quelle version tourne réellement en production. Utiliser un tag précis (un numéro de version, ou le hash du commit Git) rend les déploiements reproductibles et traçables.
push, pull, save, load : le vocabulaire du transfert
push et pull transfèrent une image depuis ou vers un registre distant, en passant par le réseau. save et load font l'équivalent mais via un simple fichier .tar, utile quand aucune connexion au registre n'est possible (environnement isolé, dit "air-gapped"). Il existe aussi export/import, qui concernent un conteneur (pas une image) et perdent l'historique des couches — à ne pas confondre avec save/load.
Piège courant
Oublier docker login avant un push provoque une erreur d'authentification peu claire pour un débutant.
Piège fréquent
Utiliser latest comme unique tag en production rend impossible de savoir avec certitude quelle version tourne réellement : deux déploiements successifs peuvent tous deux s'appeler latest tout en étant des images totalement différentes. Toujours cibler un tag précis (numéro de version ou hash de commit Git) pour des déploiements traçables et reproductibles.
Commandes & code
Gestion des images
# Construction
docker build -t mon-api:1.0 .
docker build -t mon-api:1.0 --build-arg VERSION=1.0 . # passe un argument au Dockerfile (ARG VERSION)
docker build --no-cache -t mon-api:1.0 . # ignore totalement le cache de build
docker build --progress=plain -t mon-api:1.0 . # logs détaillés, utile en debug de build
# Tagging : une image peut avoir plusieurs tags pointant vers le même contenu
docker tag mon-api:1.0 mon-api:latest
docker tag mon-api:1.0 registry.exemple.com/equipe/mon-api:1.0
# Convention de nommage complète : [registry/][namespace/]repository[:tag]
# Authentification à un registre
docker login registry.exemple.com
docker login docker.io -u mon_user # Docker Hub par défaut si aucun registre n'est précisé
# Publier une image
docker push registry.exemple.com/equipe/mon-api:1.0
docker push registry.exemple.com/equipe/mon-api:latest
# Récupérer une image
docker pull registry.exemple.com/equipe/mon-api:1.0
docker pull nginx:1.25-alpine # toujours préférer un tag précis à "latest" en prod
# Inspecter une image sans la lancer
docker inspect mon-api:1.0
docker image history mon-api:1.0 --no-trunc # détail de chaque couche, sans troncature
# Exporter / importer une image sans registre (transfert manuel, environnement air-gapped)
docker save -o mon-api.tar mon-api:1.0
docker load -i mon-api.tar
# Exporter un conteneur en cours (différent d'une image : perd l'historique des couches)
docker export mon-conteneur > snapshot.tar
docker import snapshot.tar mon-api:snapshot
# Nettoyage ciblé des images
docker images -f "dangling=true" -q | xargs -r docker rmi # supprime les images sans tag
docker images --format "{{.Repository}}:{{.Tag}}" | grep "mon-api"| Commande | Effet |
|---|---|
docker tag | crée un alias vers la même image (aucun octet copié) |
docker push/pull | transfère depuis/vers un registre distant |
docker save/load | exporte/importe une image en fichier .tar local |
docker export/import | snapshot d'un conteneur, sans historique de couches |
Résumé
- Un tag n'est qu'un alias léger ;
docker tagne duplique rien sur le disque. - Toujours cibler un tag précis en production (
nginx:1.25-alpine), jamaislatestsans contrôle. save/loadtransfère une image sans registre (air-gapped) ;export/importfait pareil pour un conteneur mais perd les couches.
Exercices pratiques
Mission : livrer une image en environnement air-gapped sans jamais utiliser latest
Objectif : Préparer un transfert d'image sans registre et justifier pourquoi latest est dangereux en production.
Contexte
Le serveur de production bancaire n'a aucun accès Internet. Tu dois livrer la version 2.3.1 de mon-api, construite ailleurs, sans jamais passer par un push/pull réseau, et sans jamais t'appuyer sur le tag latest.