1. Comprendre les images Docker
Une image Docker est un template read-only contenant tout ce dont une application a besoin : code, runtime, librairies, variables d'env et config. Les images sont composées de layers (couches) immuables empilées.
docker pull node:18-alpine # Télécharger
docker image ls # Lister
docker image inspect node:18-alpine # Détails JSON
docker image history node:18-alpine # Voir les layers
docker image rm node:18-alpine # Supprimer
Naming convention
registry/namespace/name:tag
nginx # = docker.io/library/nginx:latest
nginx:alpine # Image nginx avec tag alpine
monuser/monapp:1.0.0 # Image personnelle sur Docker Hub
ghcr.io/org/app:v2 # GitHub Container Registry
2. Layers & Cache
Chaque instruction dans un Dockerfile crĂ©e un layer. Les layers sont partagĂ©s entre images â ce qui Ă©conomise du stockage et accĂ©lĂšre les builds.
# docker image history node:18-alpine (exemple simplifié)
IMAGE CREATED SIZE CREATED BY
a8b3c4d5e6 2 days 0B CMD ["node"]
f7g8h9i0j1 2 days 2.1MB ENV NODE_VERSION=18.x.x
k2l3m4n5o6 5 days 5.2MB RUN apk add --no-cache npm
p7q8r9s0t1 5 days 7.1MB RUN apk add --no-cache nodejs
u2v3w4x5y6 12 days 7.3MB /bin/sh -c #(nop) ADD alpine
Cache invalidation
Docker utilise le cache dÚs que possible. Si une instruction (et tout ce qui précÚde) n'a pas changé, la couche est réutilisée :
# BAD â COPY . invalide le cache tĂŽt â tout est reconstruit
FROM node:18-alpine
COPY . .
RUN npm install
# GOOD â package.json copiĂ© en premier â cache npm stable
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
3. Structure d'un Dockerfile
# Dockerfile pour une app Node.js
# 1. Image de base
FROM node:18-alpine
# 2. Métadonnées
LABEL maintainer="dev@example.com"
LABEL version="1.0"
# 3. Répertoire de travail
WORKDIR /app
# 4. Variables d'environnement
ENV NODE_ENV=production \
PORT=3000
# 5. Copier les dépendances en premier (cache)
COPY package*.json ./
RUN npm ci --only=production
# 6. Copier le reste du code
COPY . .
# 7. Port exposé (documentation)
EXPOSE 3000
# 8. Commande de démarrage
CMD ["node", "server.js"]
4. Instructions Dockerfile clés
FROM
FROM ubuntu:22.04 # Image de base obligatoire
FROM scratch # Image vide (binaires statiques)
FROM node:18 AS builder # Alias pour multi-stage
RUN
# Forme shell (s'exécute dans /bin/sh -c)
RUN apt-get update && apt-get install -y curl
# Forme exec (recommandĂ©e â pas de shell)
RUN ["apt-get", "update"]
# Combiner pour réduire les layers
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
curl git \
&& rm -rf /var/lib/apt/lists/*
COPY vs ADD
COPY src/ /app/src/ # Copie simple (préférer COPY)
COPY --chown=node:node . . # Avec propriétaire
ADD archive.tar.gz /app/ # ADD décompresse les archives
ADD https://url/file /app/ # ADD tĂ©lĂ©charge (dĂ©conseillĂ© â RUN curl)
CMD vs ENTRYPOINT
# CMD â commande par dĂ©faut, remplaçable avec docker run <cmd>
CMD ["npm", "start"]
# ENTRYPOINT â binaire fixe, les args s'ajoutent aprĂšs
ENTRYPOINT ["node"]
CMD ["server.js"]
# â docker run myapp app.js exĂ©cute: node app.js
# ENTRYPOINT + CMD ensemble (pattern recommandé)
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["node", "server.js"]
ARG vs ENV
# ARG â disponible seulement pendant le BUILD
ARG BUILD_VERSION=1.0
RUN echo "Building $BUILD_VERSION"
# ENV â disponible Ă BUILD et RUNTIME
ENV PORT=3000
ENV DATABASE_URL="" # valeur vide, Ă surcharger au run
# Passer ARG au build
docker build --build-arg BUILD_VERSION=2.1 -t myapp .
5. docker build
# Build basique depuis le dossier courant
docker build -t monapp:1.0 .
# Spécifier un Dockerfile alternatif
docker build -f Dockerfile.prod -t monapp:prod .
# Forcer la reconstruction sans cache
docker build --no-cache -t monapp .
# Passer des build args
docker build --build-arg VERSION=2.0 -t monapp:2.0 .
# Voir les étapes du build
docker build --progress=plain -t monapp .
# Tags multiples
docker build -t monapp:latest -t monapp:1.0.0 .
.dockerignore
# .dockerignore â exclut des fichiers du contexte de build
node_modules/
.git/
.env
*.log
dist/
coverage/
README.md
.DS_Store
6. Bonnes pratiques
- Toujours utiliser des images de base versionnées (
node:18-alpine, pasnode:latest) - Préférer les variantes alpine ou slim pour réduire la taille
- Regrouper les
RUNliĂ©s pour minimiser les layers - Nettoyer les caches apt/apk dans le mĂȘme
RUN - Copier
package*.jsonavantCOPY . .pour optimiser le cache - Utiliser
.dockerignorepour exclurenode_modules/,.git/ - Ne pas stocker de secrets dans les layers (utiliser les secrets Docker ou les variables d'env au runtime)
Taille des images : Utiliser
docker image ls pour comparer.
node:18 â 950 MB vs node:18-alpine â 115 MB vs
node:18-slim â 240 MB.