Retour au cours

infra / docker

Gestion des images (build/tag/push/pull)

Leçon 41 exercice

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 latest est dangereux à utiliser sans discipline en production
  • Publier et récupérer une image avec docker push/docker pull aprè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.

CommandeEffet
docker tagCrée un alias vers la même image (aucune copie)
docker push / pullTransfère depuis/vers un registre distant
docker save / loadExporte/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

bash
# 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"
CommandeEffet
docker tagcrée un alias vers la même image (aucun octet copié)
docker push/pulltransfère depuis/vers un registre distant
docker save/loadexporte/importe une image en fichier .tar local
docker export/importsnapshot d'un conteneur, sans historique de couches

Résumé

  • Un tag n'est qu'un alias léger ; docker tag ne duplique rien sur le disque.
  • Toujours cibler un tag précis en production (nginx:1.25-alpine), jamais latest sans contrôle.
  • save/load transfère une image sans registre (air-gapped) ; export/import fait pareil pour un conteneur mais perd les couches.

Exercices pratiques

1 disponible
1

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.

Résoudre l’exercice →