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.

5 min read
Déverrouillez votre potentiel

avec React Router 7

Vous en avez marre de...

❌ perdre du temps à chercher des informations éparpillées
❌ ne pas avoir de retour sur votre progression
Assistant IA spécialisé

Posez vos questions 24/7 à notre IA experte en React Router 7

Quiz interactifs

Validez vos acquis avec des quiz personnalisés et un feedback instantané

9 modules
53 leçons
Accès à vie
460.75

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_modules de 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 :

  1. télécharger les deps de dev pour builder (react-router/dev, @types/*, etc.) ;
  2. installer uniquement les deps prod (react, @prisma/client) ;
  3. copier le build final et rien d’autre.
Dockerfile
1
# Étape 1 : environnement de build
2
FROM node:22-alpine AS dev-deps
3
WORKDIR /app
4
COPY . .
5
RUN npm ci # installe deps & devDeps
6
7
# Étape 2 : uniquement les deps de prod
8
FROM node:22-alpine AS prod-deps
9
WORKDIR /app
10
COPY package*.json ./
11
RUN npm ci --omit=dev # 200 Mo de gagnés 💡
12
13
# Étape 3 : build de l’app
14
FROM node:22-alpine AS build
15
WORKDIR /app
16
COPY --from=dev-deps /app .
17
RUN npm run build
18
19
# Étape 4 : image finale ultra-slim
20
FROM node:22-alpine
21
WORKDIR /app
22
COPY package*.json ./
23
COPY --from=prod-deps /app/node_modules ./node_modules
24
COPY --from=build /app/build ./build
25
CMD ["npm","run","start"]

Ce qu’il se passe sous le capot

ÉtapeContenu principalTaille (≈)
dev-depsrepo complet + devDeps750 Mo
prod-depsnode_modules minifiés220 Mo
builddossier /build (client + server JS)45 Mo
finalenode:22-alpine + deps prod + build only160 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

.dockerignore
1
.react-router
2
node_modules
3
build
4
*.log
5
tests

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

  1. Changer la version de Node Dans la vidéo je switch de node:20-alpine à node:22-alpine simplement en modifiant la première ligne. Tout le pipeline suit – zéro surprise.
  2. Réduire la taille des images
    • npm ci --omit=dev
    • --production n’est plus nécessaire depuis npm 9.
    • Utilise alpine (libc musl) pour 80 Mo VS 180 Mo (slim).
  3. Éviter les cache bust inutiles Copie en premier le package.json ; si seul ton code change, l’étape npm ci reste cachée.
    Dockerfile {5-8}
    1
    COPY package*.json ./
    2
    RUN npm ci --omit=dev
    3
    COPY . .

Tester localement avant la CI

Terminal
1
docker build -t rr7:local .
2
docker run -d --name rr7 -p 3000:3000 rr7:local
3
open http://localhost:3000

Besoin d’explorer ? Docker Desktop → rr7Files : 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 à :

.github/workflows/docker-image.yml
1
- name: Build the Docker image
2
run: docker build . --file Dockerfile --tag my-image:${{ github.sha }}

Ajoute Login & Push vers Docker Hub :

{2,5-12} .github/workflows/docker-image.yml
1
- uses: docker/login-action@v2
2
with:
3
username: ${{ secrets.DOCKERHUB_USERNAME }}
4
password: ${{ secrets.DOCKERHUB_TOKEN }}
5
6
- uses: docker/build-push-action@v3
7
with:
8
context: .
9
push: true
10
tags: "${{ 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

SymptomCause probableFix rapide
Cannot find module '@prisma/client'DevDeps supprimées trop tôtGarde @prisma/client en dependencies
Timeout GitHub Actions (>6 min)Cache Docker désactivéactions/cache@v4 sur /home/runner/.npm
Image > 500 MoCopie tout le repo.dockerignore, multi-stage, npm ci --omit=dev

Pour aller plus loin

  • Mettre la variable NODE_ENV=production (inutile depuis Node 20 mais requis si tu actives certaines optimisations).
  • Passer à distroless/node pour grapiller encore 25 Mo (mais debugging plus complexe).
  • Ajouter l’option --platform=linux/amd64,linux/arm64 dans docker/build-push-action pour préparer l’image Apple Silicon.

TL;DR

  1. Multi-stage = la clé pour une image légère.
  2. Copie le minimum dans l’étape finale : node_modules prod + /build.
  3. .dockerignore évite le gras involontaire.
  4. Un Dockerfile bien pensé accélère la CI et réduit la facture du VPS.
  5. Tu peux maintenant pousser l’image depuis GitHub Actions et la lancer sur ton serveur (voir leçon suivante).
Premium
Quiz interactif
Testez vos connaissances et validez votre compréhension du module avec notre quiz interactif.
1

Comprendre les concepts fondamentaux

Quelle est la principale différence entre les composants client et serveur dans React ?

Les composants client s'exécutent uniquement dans le navigateur
Les composants serveur peuvent utiliser useState
Les composants client sont plus rapides
Il n'y a aucune différence significative
2

Optimisation des performances

Quelle technique est recommandée pour éviter les rendus inutiles dans React ?

Utiliser React.memo pour les composants fonctionnels
Ajouter plus d'états locaux
Éviter d'utiliser les props
Toujours utiliser les class components
3

Architecture des données

Quel hook permet de gérer les effets de bord dans un composant React ?

useEffect
useState
useMemo
useContext
4

Gestion des erreurs

Comment implémenter la gestion des erreurs pour les requêtes API dans React ?

Utiliser try/catch avec async/await
Ignorer les erreurs
Toujours afficher un message d'erreur
Rediriger l'utilisateur
5

Déploiement et CI/CD

Quelle est la meilleure pratique pour déployer une application React en production ?

Utiliser un service CI/CD comme GitHub Actions
Copier les fichiers manuellement via FTP
Envoyer le code source complet
Ne jamais mettre à jour l'application

Débloquez ce quiz et tous les autres contenus premium en achetant ce cours