06 - Le .dockerignore
Ce que tu vas apprendre
- Ce qu'est le build context et pourquoi il est envoye au daemon
- Pourquoi tes builds sont lents sans
.dockerignore - La syntaxe du fichier
.dockerignore - Quoi ignorer et pourquoi
- Comment mesurer la taille du build context
Prerequisites
- Avoir lu l'article 05 - Layers & cache
- Un projet avec un Dockerfile
Le build qui a pris 2 minutes... a démarrer
Je travaillais sur un monorepo avec un dossier data/ de 3 Go contenant des dumps de base de donnees pour les tests locaux. Le docker build prenait 2 minutes avant meme de commencer la première instruction. La ligne Sending build context to Docker daemon 3.2GB restait affichee pendant que le daemon avalait tout le répertoire.
La solution a pris 10 secondes : ajouter une ligne dans .dockerignore.
Le build context, c'est quoi
Quand tu lances docker build ., le . a la fin n'est pas juste "le répertoire courant". C'est le build context : l'ensemble des fichiers que Docker envoie au daemon pour qu'il puisse les utiliser pendant le build.
Rappel de l'article 02 : le Docker CLI et le daemon sont des processus separes. Le CLI doit envoyer les fichiers au daemon via l'API. Tout le contenu du répertoire est envoye, meme si ton Dockerfile n'utilise qu'un seul fichier.
bash# Ce repertoire contient 500 Mo de node_modules
docker build .
# Sending build context to Docker daemon 523.4MB
523 Mo envoyes. Et si ton Dockerfile ne fait que COPY package.json ./, les 500 Mo de node_modules sont envoyes pour rien.
La solution : .dockerignore
Le fichier .dockerignore fonctionne comme .gitignore. Il dit a Docker quels fichiers exclure du build context. Il se place a la racine du build context (généralement a la racine du projet).
# .dockerignore
node_modules
.git
dist
build
*.log
.env
.env.*
Avec ce fichier, Docker ne transmet plus node_modules ni .git au daemon. Le build context passe de 523 Mo a 2 Mo. Le build démarré instantanement.
Syntaxe
La syntaxe est proche de .gitignore, avec quelques différences :
# Commentaire
node_modules # Ignore le dossier node_modules
*.log # Ignore tous les fichiers .log
**/*.tmp # Ignore les .tmp dans tous les sous-repertoires
!important.log # Exception : garder important.log
.git # Ignore le dossier .git
Dockerfile # Ignore le Dockerfile lui-meme
docker-compose.yml # Ignore le compose file
L'ordre compte. La dernière regle qui match gagne :
# Ignore tout dans data/
data/
# Sauf le fichier seeds.sql
!data/seeds.sql
Les patterns disponibles :
| Pattern | Signification |
|---|---|
* |
N'importe quelle sequence de caractères (sauf /) |
? |
Un seul caractère |
** |
N'importe quel nombre de répertoires |
! |
Exception (ne pas ignorer) |
Quoi ignorer
Voici un .dockerignore complet pour un projet Node.js/Bun :
# Dependances (reinstallees dans le conteneur)
node_modules
# Git
.git
.gitignore
# Build et output
dist
build
coverage
.next
.nuxt
# Environnement
.env
.env.*
.env.local
# IDE
.vscode
.idea
*.swp
*.swo
# Docker (pas besoin dans l'image)
Dockerfile
Dockerfile.*
docker-compose*.yml
.dockerignore
# OS
.DS_Store
Thumbs.db
# Tests (si pas necessaires dans l'image)
__tests__
*.test.js
*.test.ts
*.spec.js
*.spec.ts
jest.config.*
vitest.config.*
# Documentation
README.md
CHANGELOG.md
docs/
# Logs
*.log
npm-debug.log*
Les raisons d'ignorer ces fichiers :
- Performance : moins de donnees a transférer au daemon
- Sécurité :
.envcontient des secrets. Ne jamais les envoyer dans le build context. - Correcte du build :
node_modulesde l'hote peut contenir des binaires compiles pour un OS différent (Mac vs Linux). Il faut reinstaller dans le conteneur. - Taille de l'image : si tu fais
COPY . ., tout ce qui est dans le build context peut finir dans l'image.
Mesurer le build context
Pour voir la taille du build context :
bash# Methode simple : regarde le message au debut du build
docker build .
# Sending build context to Docker daemon 2.1MB
# Methode precise : tar le build context et mesure
tar -cf - --exclude-from=.dockerignore . | wc -c | numfmt --to=iec
Sur un projet type, voici ce que ca donne :
| État | Taille du build context |
|---|---|
Sans .dockerignore |
500 Mo - 2 Go |
Avec .dockerignore basique |
5 - 50 Mo |
Avec .dockerignore strict |
500 Ko - 5 Mo |
Le piège du COPY . .
Sans .dockerignore, un COPY . . dans ton Dockerfile copie tout dans l'image. Y compris :
- Tes fichiers
.envavec les secrets de prod - Le dossier
.git(qui peut etre énorme) - Les
node_modulesde ton Mac (incompatibles avec Linux) - Les fichiers temporaires de ton IDE
Meme si ces fichiers ne sont pas utilises par l'application, ils sont dans l'image. N'importe qui avec acces a l'image peut les extraire.
bash# Extraire les fichiers d'une image
docker create --name temp mon-app
docker cp temp:/app/.env ./env-volé
docker rm temp
Le .dockerignore est ta première ligne de defense.
.dockerignore et multi-stage
Avec les multi-stage builds, le .dockerignore s'applique a tous les stages. Tu ne peux pas avoir un .dockerignore différent par stage.
Si tu as besoin de fichiers différents pour chaque stage, sois precis dans tes COPY :
dockerfile# Stage build : copie tout le code
FROM node:22-slim AS builder
COPY src/ ./src/
COPY package.json ./
RUN npm ci && npm run build
# Stage prod : copie uniquement le build
FROM node:22-slim
COPY --from=builder /app/dist ./dist
Buildkit et le build context
Avec BuildKit (le builder par défaut depuis Docker 23), le transfert du build context est incremental. Docker n'envoie que les fichiers effectivement utilises par les instructions COPY et ADD.
Ca veut dire que meme sans .dockerignore, les fichiers non copies ne sont pas transferes. Mais le .dockerignore reste utile pour :
- Empecher les erreurs de
COPY . . - Accelerer le calcul des checksums
- Proteger contre l'inclusion accidentelle de secrets
Sur paltemps.fr, chaque projet a un .dockerignore créé en meme temps que le Dockerfile. C'est un reflexe.
Résumé
- Le build context est l'ensemble des fichiers envoyes au daemon Docker
- Sans
.dockerignore, tout le répertoire est envoye (y comprisnode_moduleset.git) - Le
.dockerignorefonctionne comme.gitignoreet réduit drastiquement le transfert - Ignorer :
node_modules,.git,.env, les fichiers de build, les tests, la doc - Le
.dockerignoreprotégé aussi contre l'inclusion de secrets dans l'image
Precedent : 05 - Layers & cache | Suivant : 07 - Multi-stage builds