Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 410 minIntermédiaire

Images Docker : couches, étiquettes et registres

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • décomposer le nom complet d'une image : registre, espace, dépôt, étiquette ;
  • distinguer une étiquette mobile d'une empreinte immuable ;
  • expliquer le partage des couches et le piège du fichier supprimé ;
  • choisir une image de base fiable et légère.

4 exercices corrigés1 schéma

Une image Docker est un empilement de couches en lecture seule, identifiée par un nom, une étiquette (tag) et une empreinte unique (digest), et stockée dans un registre comme Docker Hub. Ce chapitre explique comment se lit le nom d'une image, pourquoi latest est un piège, comment les couches sont partagées entre images et conteneurs, et comment choisir une image de base : officielle, slim, alpine ou durcie.

Lire le nom d'une image

Le nom complet d'une image a cette forme :

text
[registre/][espace/]dépôt[:étiquette][@sha256:empreinte]

Quand une partie manque, Docker la complète : le registre par défaut est Docker Hub (docker.io), l'espace des images officielles est library, l'étiquette par défaut est latest.

Ce que tu écrisCe que Docker comprend
nginxdocker.io/library/nginx:latest
nginx:1.30-alpinedocker.io/library/nginx:1.30-alpine
grafana/grafana:12.2.0docker.io/grafana/grafana:12.2.0 (espace de l'éditeur)
ghcr.io/sorbier/sorbier-frais:2.4.0Registre de GitHub, espace sorbier, dépôt sorbier-frais, étiquette 2.4.0
registre.ad.sorbier.example:5000/outils/sauvegarde:1.2Un registre privé interne, sur le port 5000

Étiquettes et empreintes

Une étiquette est un nom lisible, posé sur une image par celui qui la publie. Elle est mobile : l'éditeur peut la déplacer sur une nouvelle image. nginx:1.30-alpine désignait en avril 2026 la version 1.30.0, et en juillet la 1.30.4. latest n'est qu'une étiquette comme les autres, celle qu'on prend quand on n'en précise aucune : elle ne garantit pas d'être la plus récente, et surtout pas d'être stable.

Une empreinte (digest) est le hachage SHA-256 du contenu de l'image. Elle est immuable : si un seul octet change, l'empreinte change.

bash
docker pull nginx:1.30-alpine
docker image inspect --format '{{index .RepoDigests 0}}' nginx:1.30-alpine
text
nginx@sha256:5c1b9e1f8c0f3a…

L'empreinte complète compte 64 caractères hexadécimaux ; elle est raccourcie ici.

RéférenceStabilitéUsage
nginx ou nginx:latestChange à chaque publication, y compris de version majeureUn essai, jamais un serveur
nginx:1Suit toutes les versions 1.xRarement souhaitable
nginx:1.30-alpineSuit les correctifs de la 1.30Le bon compromis pour un service : correctifs de sécurité sans changement de fonctionnement
nginx:1.30.4-alpineFixe par conventionReproductibilité forte, mais il faut changer l'étiquette à chaque correctif
nginx@sha256:…Garantie par le registreLa référence la plus sûre, utilisée par la CI pour déployer exactement l'image testée

Les couches d'une image

Chaque instruction du Dockerfile qui modifie les fichiers (RUN, COPY, ADD) ajoute une couche : la liste des fichiers ajoutés, modifiés ou supprimés par rapport à la couche du dessous. Les autres instructions (CMD, ENV, EXPOSE) ne changent que les métadonnées.

bash
docker history nginx:1.30-alpine

L'historique liste chaque couche, la commande qui l'a produite et sa taille, de la plus récente à la plus ancienne.

Trois conséquences pratiques :

  • Les couches sont partagées. Dix images construites sur node:24-slim ne stockent qu'une fois les couches de node:24-slim, et un docker pull ne télécharge que les couches qui manquent (Already exists pour les autres).
  • Un conteneur ajoute une couche inscriptible, propre à lui, au-dessus des couches de l'image. Quand il modifie un fichier de l'image, OverlayFS copie d'abord ce fichier dans la couche inscriptible (copy-on-write) : l'image n'est jamais modifiée.
  • Supprimer un fichier dans une couche ne l'efface pas des couches précédentes. Il est simplement masqué. Un secret copié dans une couche puis supprimé dans la suivante reste lisible par quiconque récupère l'image.
inscriptible, conteneur 1inscriptible, conteneur 2COPY src ./src : le codeRUN npm ci : les dépendancesconfiguration de l'imageNode.js 24Debian réduiteLecture-écriture,une par conteneur, jetableCouches desorbier-fraisCouches denode:24-slimpartagées par toutesles images construitessur cette baseLes couches de l'image sont en lecture seule et stockées une seule fois.Modifier un fichier le copie d'abord dans la couche inscriptible (copy-on-write).
Les couches en lecture seule sont partagées ; chaque conteneur n'a en propre que sa couche inscriptible

Choisir une image de base

Sur Docker Hub, trois catégories d'images n'inspirent pas la même confiance :

CatégorieRepèreConfiance
Docker Official ImagesPas d'espace (nginx, mysql, node), badge Docker Official ImageMaintenues par une équipe dédiée avec les éditeurs, reconstruites à chaque correctif de sécurité
Verified PublisherEspace de l'éditeur (grafana/grafana), badge Verified PublisherPubliées par l'éditeur du logiciel lui-même
Images communautairesEspace d'un particulier (jdupont/nginx-php)Aucune garantie : contenu, mises à jour et intentions inconnus

Pour une même image officielle, plusieurs variantes existent :

VarianteBaseTaille relativePour
node:24Debian complète, avec compilateursLa plus lourde (plus d'un gigaoctet)Construire, compiler des modules natifs
node:24-slimDebian réduitePlusieurs fois plus légèreFaire tourner l'application : bon choix par défaut
node:24-alpineAlpine Linux et sa bibliothèque C muslLa plus légère des troisLes images minimales, si l'application tolère musl
distroless, scratchPresque rien, ou rien du tout : pas de shell, pas de gestionnaire de paquetsMinimaleUn binaire autonome (Go, Rust) ; surface d'attaque minimale
Docker Hardened Images (dhi.io)Debian ou Alpine durcies, gratuites depuis décembre 2025MinimaleDes images réduites au strict nécessaire, reconstruites à chaque correctif

Les registres et leurs limites

RegistreAdresseParticularité
Docker Hubdocker.ioRegistre par défaut ; téléchargements limités sans compte
GitHub Container Registryghcr.ioLié aux dépôts GitHub, idéal avec GitHub Actions
Registre de GitLabregistry.gitlab.comLié aux projets GitLab
HarborAuto-hébergéRegistre d'entreprise : comptes, projets, analyse de vulnérabilités, réplication
registry:3Auto-hébergéLe registre libre minimal (projet Distribution), à protéger soi-même (chapitre 12)

Docker Hub limite les téléchargements depuis avril 2025 : sans compte, 10 téléchargements par heure par adresse IPv4 (ou par préfixe IPv6 /64) ; avec un compte gratuit, 100 par heure. Toute une salle de TP qui sort par la même adresse publique atteint vite la limite sans compte.

bash
docker login            # identifiants Docker Hub, ou un jeton d'accès personnel
docker logout

Pour transférer une image sans registre, vers une machine isolée d'Internet par exemple :

bash
docker save -o sorbier-frais.tar ghcr.io/sorbier/sorbier-frais:2.4.0
docker load -i sorbier-frais.tar

Exercices

Exercice 1 sur 4 Décomposer des noms d'images Réussi À revoir

Pour chaque image, donne le registre, l'espace, le dépôt et l'étiquette réellement utilisés.

  1. mysql
  2. zabbix/zabbix-server-mysql:alpine-7.0-latest
  3. ghcr.io/sorbier/sorbier-frais@sha256:9b2f…
  4. localhost:5000/outils/sauvegarde
Voir la réponseMasquer la réponse de l'exercice 1
  1. Registre docker.io, espace library (image officielle), dépôt mysql, étiquette latest.
  2. Registre docker.io, espace zabbix (l'éditeur), dépôt zabbix-server-mysql, étiquette alpine-7.0-latest.
  3. Registre ghcr.io, espace sorbier, dépôt sorbier-frais, pas d'étiquette : l'image est désignée par son empreinte, ce qui la fixe définitivement.
  4. Registre localhost:5000 (un nom suivi d'un port est lu comme un registre), espace outils, dépôt sauvegarde, étiquette latest.

Tu avais trouvé ?

Exercice 2 sur 4 Le partage des couches Réussi À revoir

Sur srv-gestion, trois images sont construites sur node:24-slim, dont les couches pèsent 220 Mo au total. Les couches propres à chaque application pèsent 35 Mo, 60 Mo et 15 Mo. Quatre conteneurs tournent à partir de la première image, deux à partir de la deuxième. Combien d'espace disque les images occupent-elles, couches inscriptibles des conteneurs mises à part ? Combien faudrait-il si les couches n'étaient pas partagées entre images ?

Voir la réponseMasquer la réponse de l'exercice 2

Avec partage : la base une seule fois, plus les couches propres à chaque image : 220 + 35 + 60 + 15 = 330 Mo. Le nombre de conteneurs ne change rien : ils réutilisent les couches de leur image et n'ajoutent que leur couche inscriptible.

Sans partage : chaque image porterait sa propre copie de la base : (220 + 35) + (220 + 60) + (220 + 15) = 255 + 280 + 235 = 770 Mo, soit 440 Mo de plus.

Tu avais trouvé ?

Exercice 3 sur 4 La salle de TP bloquée Réussi À revoir

Une salle de 24 étudiants qui sortent sur Internet par la même adresse IPv4 publique lance en même temps docker pull de trois images différentes, sans compte Docker Hub. À partir de quel téléchargement les erreurs apparaissent-elles, et que propose l'administrateur ?

Voir la réponseMasquer la réponse de l'exercice 3

Sans compte, Docker Hub accepte 10 téléchargements par heure et par adresse IPv4. La salle en demande 24 × 3 = 72 : les 10 premiers passent, les erreurs commencent au onzième (toomanyrequests).

Solutions : que chaque étudiant se connecte avec un compte gratuit (docker login, 100 téléchargements par heure et par compte) ; installer un registre miroir (cache) dans le réseau de l'établissement, qui ne télécharge chaque image qu'une fois ; ou préparer les images à l'avance (docker save, puis docker load sur chaque poste).

Tu avais trouvé ?

Exercice 4 sur 4 Le secret effacé Réussi À revoir

Un développeur a écrit ces lignes dans un Dockerfile, puis publié l'image sur Docker Hub en se disant que le fichier est supprimé :

dockerfile
COPY .env /app/.env
RUN npm run migrate && rm /app/.env

A-t-il raison ? Que doit-il faire maintenant ?

Voir la réponseMasquer la réponse de l'exercice 4

Non. COPY .env crée une couche qui contient le fichier ; le rm de l'instruction suivante crée une autre couche qui le masque, sans l'effacer de la précédente. N'importe qui peut télécharger l'image, extraire ses couches (docker save, puis une archive tar) et lire .env.

Ce qu'il doit faire, dans l'ordre :

  1. considérer les secrets comme compromis et les changer tous (mot de passe de base, clés d'API) ;
  2. supprimer l'image et ses étiquettes du registre ;
  3. corriger le Dockerfile : ajouter .env au .dockerignore, ne jamais copier de secret dans une image, et fournir la configuration au démarrage du conteneur ; les migrations se lancent au déploiement, pas à la construction.

Tu avais trouvé ?

Chapitre terminé !

Fais les 4 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Écrire un Dockerfile : instructions et bonnes pratiquesRevoir le sommaire du cours