Configurer le fichier Dockerfile
Optimise ton Dockerfile : multi-stage, image légère, build rapide et déploiement facile pour ton app React Router 7. Passe à la pratique sans galère.
Pourquoi optimiser ton Dockerfile ?
Docker est la « machine virtuelle jetable » qui fera tourner ton app sur n’importe quel serveur. Sans optimisation, tu transportes :
- tous les fichiers du repo (y compris
/tests,.env.example, images...), - les devDependencies inutiles en prod,
- parfois même les
node_modulesde ton OS.
Résultat :
- image de plusieurs Go,
- build interminable sur GitHub Actions,
- stockage saturé sur le VPS.
Dans cette leçon on transforme un Dockerfile naïf en image légère, reproductible et sûre, en s’appuyant sur les points clés montrés dans la vidéo précédente.
Les trois couches d’une image efficace
L’approche « multi-stage » te permet de :
- télécharger les deps de dev pour builder (
react-router/dev,@types/*, etc.) ; - installer uniquement les deps prod (
react,@prisma/client) ; - copier le build final et rien d’autre.
1# Étape 1 : environnement de build2FROM node:22-alpine AS dev-deps3WORKDIR /app4COPY . .5RUN npm ci # installe deps & devDeps67# Étape 2 : uniquement les deps de prod8FROM node:22-alpine AS prod-deps9WORKDIR /app10COPY package*.json ./11RUN npm ci --omit=dev # 200 Mo de gagnés 💡1213# Étape 3 : build de l’app14FROM node:22-alpine AS build15WORKDIR /app16COPY --from=dev-deps /app .17RUN npm run build1819# Étape 4 : image finale ultra-slim20FROM node:22-alpine21WORKDIR /app22COPY package*.json ./23COPY --from=prod-deps /app/node_modules ./node_modules24COPY --from=build /app/build ./build25CMD ["npm","run","start"]
Ce qu’il se passe sous le capot
| Étape | Contenu principal | Taille (≈) |
|---|---|---|
| dev-deps | repo complet + devDeps | 750 Mo |
| prod-deps | node_modules minifiés | 220 Mo |
| build | dossier /build (client + server JS) | 45 Mo |
| finale | node:22-alpine + deps prod + build only | 160 Mo 🎉 |
Le reste est jeté lors du FROM suivant.
Seule la dernière image est poussée sur Docker Hub ou exécutée sur ton VPS.
Les autres fichiers à ne pas oublier
1.react-router2node_modules3build4*.log5tests
Si un chemin apparaît dans .dockerignore, Docker ne l’ajoute à aucun moment,
donc même le premier stage gagne plusieurs secondes.
Optimisations pratiques issues du transcript
- Changer la version de Node
Dans la vidéo je switch de
node:20-alpineànode:22-alpinesimplement en modifiant la première ligne. Tout le pipeline suit – zéro surprise. - Réduire la taille des images
npm ci --omit=dev--productionn’est plus nécessaire depuis npm 9.- Utilise
alpine(libc musl) pour 80 Mo VS 180 Mo (slim).
- Éviter les cache bust inutiles
Copie en premier le
package.json; si seul ton code change, l’étapenpm cireste cachée.Dockerfile {5-8}1COPY package*.json ./2RUN npm ci --omit=dev3COPY . .
Tester localement avant la CI
1docker build -t rr7:local .2docker run -d --name rr7 -p 3000:3000 rr7:local3open http://localhost:3000
Besoin d’explorer ?
Docker Desktop → rr7 → Files : tu vérifies que seul /build et
node_modules sont présents.
Intégrer le build dans GitHub Actions
Le job build actuel dans .github/workflows/docker-image.yml
ressemble à :
1- name: Build the Docker image2run: docker build . --file Dockerfile --tag my-image:${{ github.sha }}
Ajoute Login & Push vers Docker Hub :
1- uses: docker/login-action@v22with:3username: ${{ secrets.DOCKERHUB_USERNAME }}4password: ${{ secrets.DOCKERHUB_TOKEN }}56- uses: docker/build-push-action@v37with:8context: .9push: true10tags: "${{ secrets.DOCKERHUB_USERNAME }}/rr7:${{ github.sha }}"
Ainsi, la CI produit la même image que tu viens de tester en
local, prête à être docker pull sur ton VPS (voir leçon
Configurer les Github Actions).
Résoudre les erreurs courantes
| Symptom | Cause probable | Fix rapide |
|---|---|---|
Cannot find module '@prisma/client' | DevDeps supprimées trop tôt | Garde @prisma/client en dependencies |
| Timeout GitHub Actions (>6 min) | Cache Docker désactivé | actions/cache@v4 sur /home/runner/.npm |
| Image > 500 Mo | Copie tout le repo | .dockerignore, multi-stage, npm ci --omit=dev |
Note
La doc officielle
Pour aller plus loin
- Mettre la variable
NODE_ENV=production(inutile depuis Node 20 mais requis si tu actives certaines optimisations). - Passer à
distroless/nodepour grapiller encore 25 Mo (mais debugging plus complexe). - Ajouter l’option
--platform=linux/amd64,linux/arm64dansdocker/build-push-actionpour préparer l’image Apple Silicon.
TL;DR
- Multi-stage = la clé pour une image légère.
- Copie le minimum dans l’étape finale :
node_modulesprod +/build. .dockerignoreévite le gras involontaire.- Un Dockerfile bien pensé accélère la CI et réduit la facture du VPS.
- Tu peux maintenant pousser l’image depuis GitHub Actions et la lancer sur ton serveur (voir leçon suivante).
Important
Tu as un doute, une erreur opaque ?
Viens sur le Discord Algomax : on débogue ton Dockerfile ensemble !
Comprendre les concepts fondamentaux
Quelle est la principale différence entre les composants client et serveur dans React ?
Optimisation des performances
Quelle technique est recommandée pour éviter les rendus inutiles dans React ?
Architecture des données
Quel hook permet de gérer les effets de bord dans un composant React ?