Avancé45 min35 XP
Objectifs de cette leçon
- Réduire la taille des images Docker
- Utiliser le cache Docker efficacement
- Sécuriser les conteneurs en production
Optimisation et bonnes pratiques 🚀
Pourquoi optimiser ?
Image non optimisée : ┌──────────────────────────────┐ │ Ubuntu 22.04 (800 Mo) │ │ + Node.js 18 (100 Mo) │ │ + npm packages (200 Mo) │ │ + Code source (50 Mo) │ │ + Dev tools (150 Mo) │ │ = 1.3 Go total 😱 │ └──────────────────────────────┘ Image optimisée : ┌──────────────────────────────┐ │ Alpine 3.18 (5 Mo) │ │ + Node.js 18 (50 Mo) │ │ + Production (80 Mo) │ │ = 135 Mo total 🎉 │ └──────────────────────────────┘
Résultat : 90% plus léger !
1. Multi-stage builds
Le multi-stage build construit dans une image complète puis copie uniquement le nécessaire dans une image finale légère :
# Étape 1 : Build (image complète) FROM node:18 AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Étape 2 : Production (image légère) FROM node:18-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules EXPOSE 3000 CMD ["node", "dist/server.js"]
Exemple React + Nginx
# Build FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Production FROM nginx:alpine COPY --from=builder /app/build /usr/share/nginx/html EXPOSE 80
2. Réduire la taille des images
Choisir la bonne image de base
| Image | Taille | Usage |
|---|---|---|
ubuntu:22.04 | 800 Mo | Quand tu as besoin de tout |
node:18 | 900 Mo | Développement |
node:18-alpine | 178 Mo | Production |
node:18-slim | 200 Mo | Production alternative |
scratch | 0 Mo | Binaires statiques |
Combiner les RUN
# Mauvais : 4 couches RUN apt-get update RUN apt-get install -y curl RUN apt-get install -y wget RUN rm -rf /var/lib/apt/lists/* # Bon : 1 couche RUN apt-get update && \ apt-get install -y curl wget && \ rm -rf /var/lib/apt/lists/*
3. .dockerignore
# Tout ce qui n'est PAS nécessaire à la production node_modules npm-debug.log .env .env.local .git .gitignore Dockerfile docker-compose.yml README.md .vscode coverage tests test __tests__ *.test.js *.spec.js .github .dockerignore
4. Sécurité
Utiliser un utilisateur non-root
# Mauvais : root par défaut FROM node:18-alpine WORKDIR /app COPY . . CMD ["node", "server.js"] # Bon : utilisateur non-root FROM node:18-alpine RUN addgroup -S appgroup && adduser -S appuser -G appgroup WORKDIR /app COPY --chown=appuser:appgroup . . USER appuser CMD ["node", "server.js"]
Scanner les vulnérabilités
# Scanner une image docker scout cves mon-app:1.0 # Scanner Docker Hub docker scout quickview nginx:alpine
5. Le cache Docker
Stratégie de cache
# 1. Système en premier (change rarement) FROM node:18-alpine RUN apk add --no-cache python3 make g++ # 2. Dépendances ensuite (change quand package.json change) WORKDIR /app COPY package*.json ./ RUN npm ci # 3. Code source en dernier (change souvent) COPY . .
6. Variables d'environnement
# Ne jamais硬编码 les secrets # Mauvais ENV DB_PASSWORD=secret123 # Bon # Passer au runtime avec -e ou --env-file
7. Santé (healthchecks)
HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:3000/health || exit 1
# docker-compose.yml services: app: healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 3s retries: 3
8. Bonnes pratiques de production
| Pratique | Description |
|---|---|
| Image spécifique | Ne jamais utiliser latest en prod |
| Non-root | Toujours utiliser un utilisateur non-root |
| Multi-stage | Réduire la taille des images |
| Healthcheck | Vérifier la santé des services |
| Logging | Utiliser docker logs et stdout |
| Secrets | Ne jamais commit les secrets |
| Networks | Réseau dédié par application |
| Volumes | Persistance des données critiques |
Exercices 🎯
- Optimisation : Réduisez la taille d'une image Docker de 50%.
- Sécurité : Ajoutez un healthcheck à votre conteneur.
- Multi-stage : Créez un Dockerfile multi-stage pour une app React.
- Production : Appliquez toutes les bonnes pratiques à un projet existant.
Prochaine leçon : Projet final — architecture complète dockerisée.
Optimisation d'image
Comparez avant/après1.2 GB
Taille initiale
152 MB
Après optimisation
❌ as de .dockerignore
❌ épendances de dev incluses
❌ ne seule étape de build
❌ pm install sans --production
Couches: 12Build: 5 min 30s