Kennisbank › Docker Containers › Optimiser les images Docker pour la production
docker containers gevorderd 25 August 2026

Optimiser les images Docker pour la production

Optimiser les images Docker pour la production

Optimiser les images Docker pour la production

Cet article explique comment optimiser les images Docker pour les environnements de production selon les bonnes pratiques officielles de Docker, pour les développeurs et les ingénieurs DevOps qui travaillent avec Docker.

Prérequis

- Docker Engine 24.0 ou plus - Connaissances de base des Dockerfiles et des images de conteneurs - Accès à un registre de conteneurs (par exemple Docker Hub ou un registre privé) - Une application que vous souhaitez exécuter dans un conteneur

Étapes

1. Utilisez une image de base officielle

Commencez par une image officielle actuelle comme base pour chaque image. Docker maintient ces images avec des mises à jour de sécurité régulières et une documentation claire. Les images officielles réduisent le risque de vulnérabilités dans la pile logicielle sous-jacente.

Choisissez une version spécifique plutôt que `latest` :

FROM node:20-alpine

2. Choisissez la plus petite image de base possible

Utilisez pour l'étape d'exécution la plus petite image de base possible. Les images plus petites se déploient plus rapidement et contiennent moins de composants vulnérables. Les variantes Alpine sont un bon point de départ pour de nombreuses charges de travail.

Comparez :

Grande : node:20 (environ 1 Go)
Petite : node:20-alpine (environ 180 Mo)
FROM node:20-alpine

3. Construisez avec des builds multi-étapes

Utilisez des builds multi-étapes pour séparer l'environnement de build de l'environnement d'exécution. Cela donne une image de production plus petite et plus sûre.

Étape 1 : build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build</p><p>Étape 2 : exécution
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --omit=dev
EXPOSE 3000
CMD ["node", "dist/index.js"]

4. Organisez les instructions du Dockerfile pour un cache optimal

Placez les instructions de la moins fréquemment modifiée à la plus fréquemment modifiée. Ainsi, le cache reste valide pour les couches précédentes lorsque vous ne modifiez que le code source.

FROM node:20-alpine
WORKDIR /app</p><p>Copiez d'abord les fichiers package - ils changent rarement
COPY package*.json ./
RUN npm ci</p><p>Copiez le code source - il change souvent
COPY . .</p><p>CMD ["node", "src/index.js"]

5. Évitez `COPY .` et utilisez `.dockerignore`

Ne copiez que les fichiers dont l'application a besoin. Cela réduit la taille de l'image et améliore la mise en cache.

Créez un fichier `.dockerignore` à la racine du projet :

node_modules
npm-debug.log
.git
.gitignore
Dockerfile
.dockerignore
.env
coverage
dist

Utilisez des instructions COPY ciblées :

COPY package*.json ./
COPY src/ ./src/
COPY public/ ./public/

6. Supprimez les dépendances et outils inutiles

Laissez de côté les outils de débogage et les dépendances de développement dans l'image de production. Utilisez `npm ci --omit=dev` ou l'équivalent pour votre gestionnaire de paquets.

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .

7. Reconstruisez régulièrement les images avec des dépendances mises à jour

Les images plus anciennes contiennent des vulnérabilités qui sont corrigées dans les versions plus récentes de l'image de base ou des paquets installés. Planifiez les reconstructions à un moment fixe, par exemple chaque semaine ou à chaque correctif de sécurité.

docker build --pull -t myapp:$(date +%Y%m%d) .

Le drapeau `--pull` garantit que vous récupérez toujours la version la plus récente de l'image de base.

8. Récupérez les fichiers distants pendant le build

Téléchargez les fichiers externes pendant le build plutôt que de les copier depuis le contexte. Cela évite de rendre le contexte de build Docker inutilement volumineux.

FROM alpine:3.19
RUN wget -O /usr/local/bin/tool https://example.com/tool.tar.gz \
    && tar -xzf /usr/local/bin/tool.tar.gz -C /usr/local/bin/ \
    && rm /usr/local/bin/tool.tar.gz

Vérification

Vérifiez que votre image est correctement optimisée :

Afficher la taille de l'image
docker images</p><p>Analyser les vulnérabilités (Docker Scout ou Trivy)
docker scout cves myapp:latest</p><p>Afficher les couches et leur taille
docker history myapp:latest

Une image de production pour une application Node.js devrait typiquement être inférieure à 200 Mo. Une image avec des outils de build inutiles dépasse rapidement cette taille.

Problèmes fréquents

1. L'image reste volumineuse malgré le build multi-étapes

Vérifiez que vous ne copiez pas de fichiers superflus dans l'étape d'exécution. Utilisez `docker history <image>` pour voir la taille de chaque couche. Supprimez par exemple `node_modules` du contexte de build avec `.dockerignore` et n'installez que les dépendances de production.

2. Le cache n'est pas utilisé à chaque build

Assurez-vous que l'ordre des instructions est correct. Placez `COPY package*.json ./` et `RUN npm ci` avant `COPY . .`. Si votre `package.json` change, le cache devient invalide pour toutes les couches suivantes — c'est un comportement correct.

3. L'image de base Alpine pose des problèmes de compatibilité

Alpine utilise musl libc au lieu de glibc. Certains modules natifs ne fonctionnent pas avec cela. Utilisez alors une petite image alternative comme `node:20-slim` (basée sur Debian) ou construisez avec un build multi-étapes dans lequel vous compilez le module natif dans l'étape de build.

Reconstruire régulièrement n'est pas une activité ponctuelle mais un processus continu — le paysage de la sécurité change constamment, et vos images doivent suivre ce mouvement.

← Retour à la base de connaissances
← Terug naar kennisbank