0 XP
?
Débutant50 min35 XP

Objectifs de cette leçon

  • Télécharger et gérer des images Docker
  • Comprendre le système de tags et de tailles
  • Lister et supprimer des images

Images Docker 🖼️

Qu'est-ce qu'une image Docker ?

Une image Docker est un modèle en lecture seule contenant tout ce nécessaire pour exécuter une application :

┌──────────────────────────────────┐
│           Image Docker            │
│  ┌────────────────────────────┐  │
│  │     Application (App)      │  │  ← Couche 4
│  ├────────────────────────────┤  │
│  │   Dépendances (npm, pip)   │  │  ← Couche 3
│  ├────────────────────────────┤  │
│  │  Système de fichiers       │  │  ← Couche 2
│  │  (Ubuntu/Alpine minimal)   │  │
│  ├────────────────────────────┤  │
│  │  Noyau Linux (partagé)     │  │  ← Couche 1 (base)
│  └────────────────────────────┘  │
└──────────────────────────────────┘

La structure en couches

Docker construit les images en couches empilées. Chaque instruction du Dockerfile crée une couche :

FROM node:18-alpine        # Couche 1 : base Alpine
WORKDIR /app               # Couche 2 : répertoire de travail
COPY package*.json ./      # Couche 3 : copie dépendances
RUN npm ci                 # Couche 4 : installation
COPY . .                   # Couche 5 : copie du code
CMD ["node", "server.js"]  # Couche 6 : commande par défaut

Avantage : Les couches sont mises en cache. Si vous modifiez uniquement le code, Docker ne reconstruit que les couches modifiées.


Le cache des images

Premier build :
Layer 1: FROM node:18-alpine     → Cache miss → Téléchargement
Layer 2: WORKDIR /app            → Cache miss → Création
Layer 3: COPY package*.json      → Cache miss → Copie
Layer 4: RUN npm ci              → Cache miss → Installation (30s)
Layer 5: COPY . .                → Cache miss → Copie
Layer 6: CMD ["node", ...]       → Cache miss → Configuration

Deuxième build (après modification de server.js) :
Layer 1: FROM node:18-alpine     → Cache HIT ✅
Layer 2: WORKDIR /app            → Cache HIT ✅
Layer 3: COPY package*.json      → Cache HIT ✅
Layer 4: RUN npm ci              → Cache HIT ✅
Layer 5: COPY . .                → Cache miss → Recopie
Layer 6: CMD ["node", ...]       → Cache miss → Recréation

Résultat : 2 secondes au lieu de 30 !

Les tags d'image

nginx          → Latest (par défaut, déconseillé en prod)
nginx:1.25     → Version spécifique
nginx:alpine   → Variante légère
nginx:1.25-alpine  → Version + variante
monrepo/nginx:prod  → Image dans un registre privé

Règle d'or : En production, toujours taguer une image spécifique.


Commandes essentielles pour les images

# Lister toutes les images
docker images

# Résultat :
# REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
# nginx        1.25      a8758716bb6a   2 weeks ago    187MB
# node         18-alpine 5ca1c314928a   3 weeks ago    178MB

# Télécharger une image
docker pull nginx:1.25-alpine

# Chercher une image
docker search node

# Supprimer une image
docker rmi nginx:1.25-alpine

# Supprimer toutes les images inutilisées
docker image prune -a

Construire sa propre image

Le Dockerfile

# 1. Image de base
FROM node:18-alpine

# 2. Répertoire de travail
WORKDIR /app

# 3. Copier les dépendances d'abord (cache)
COPY package*.json ./

# 4. Installer les dépendances
RUN npm ci --only=production

# 5. Copier le code source
COPY . .

# 6. Exposer le port
EXPOSE 3000

# 7. Commande de démarrage
CMD ["node", "server.js"]

Construire l'image

# Syntaxe : docker build -t <nom>:<tag> <chemin>

# Construire avec le Dockerfile actuel
docker build -t mon-app:1.0 .

# Construire avec un Dockerfile spécifique
docker build -f Dockerfile.prod -t mon-app:prod .

# Résultat :
# Step 1/7 : FROM node:18-alpine
#  ---> 5ca1c314928a
# Step 2/7 : WORKDIR /app
#  ---> Using cache
# ...
# Successfully built abc123def456
# Successfully tagged mon-app:1.0

Les .dockerignore

Comme .gitignore, le .dockerignore empêche certains fichiers d'être copiés dans l'image :

# .dockerignore
node_modules
npm-debug.log
.env
.env.local
.git
.gitignore
Dockerfile
docker-compose.yml
README.md
.vscode
coverage

Pourquoi ? Réduire la taille de l'image et éviter de copier des fichiers inutiles.


Bonnes pratiques pour les images

PratiqueMauvaisBon
Image de baseFROM ubuntu (800 Mo)FROM node:18-alpine (178 Mo)
TagFROM node:latestFROM node:18-alpine
DépendancesTout copier d'abordCopier package.json d'abord
Multi-stageNon utiliséUtiliser pour la prod
.dockerignorePas de fichierToujours en avoir un

Exercices 🎯

  1. Dockerfile : Écrivez un Dockerfile pour une app Node.js simple.
  2. Build : Construisez l'image avec docker build -t mon-app:1.0 .
  3. Cache : Modifiez le code, rebuild, et observez la vitesse grâce au cache.
  4. Optimisation : Comparez la taille avec FROM ubuntu vs FROM node:18-alpine.

Prochaine leçon : Les conteneurs Docker et leur cycle de vie.

⚡ Simulateur — Construction d'une image Docker

Étape 1/8
📝 Pseudo-code
1docker build -t mon-app .
2
3# Étape 1 : FROM node:22
4# Étape 2 : WORKDIR /app
5# Étape 3 : COPY package.json .
6# Étape 4 : RUN npm install
7# Étape 5 : COPY . .
8# Étape 6 : RUN npm run build
9# Étape 7 : CMD ["npm", "start"]
🧱 Empilement des couchesTaille totale: ~500MB
CMD npm start0KB
RUN npm run build200KB
COPY . .50KB
RUN npm install150MB
COPY package.json1KB
WORKDIR /app0KB
FROM node:22350MB

On lance la construction de l'image Docker.