0 XP
?
Intermédiaire60 min40 XP

Objectifs de cette leçon

  • Écrire un Dockerfile optimisé
  • Comprendre les instructions ADD, COPY, RUN, CMD
  • Construire des images multi-étapes

Écrire un Dockerfile 📝

Anatomy d'un Dockerfile

# Commentaire : Étape 1 - Image de base
FROM node:18-alpine

# Étape 2 - Répertoire de travail
WORKDIR /app

# Étape 3 - Copier les dépendances (pour le cache)
COPY package*.json ./

# Étape 4 - Installer les dépendances
RUN npm ci --only=production

# Étape 5 - Copier le code source
COPY . .

# Étape 6 - Variables d'environnement
ENV NODE_ENV=production

# Étape 7 - Exposer un port
EXPOSE 3000

# Étape 8 - Commande par défaut
CMD ["node", "server.js"]

Chaque instruction en détail

FROM

FROM node:18-alpine        # Alpine = léger (178 Mo)
FROM ubuntu:22.04          # Plus lourd (800 Mo)
FROM scratch               # Image vide (avancé)

Règle : Toujours commencer par FROM. C'est la première instruction.

WORKDIR

WORKDIR /app               # Définit le répertoire de travail
# Toutes les instructions suivantes s'exécutent dans /app

COPY

COPY . .                   # Copie tout le dossier actuel
COPY package*.json ./      # Copie uniquement les fichiers package
COPY --chown=node:node . . # Copie avec un propriétaire spécifique

ADD (avancé)

ADD archive.tar.gz /app    # Extrait automatiquement les archives
ADD https://example.com/file.txt /app  # Télécharge depuis une URL

Conseil : Préférez COPY à ADD sauf pour les archives.

RUN

RUN apt-get update && apt-get install -y curl  # Installation
RUN npm ci --only=production                   # Installation npm
RUN rm -rf /var/lib/apt/lists/*               # Nettoyage

Astuce : Combinez les RUN pour réduire le nombre de couches.

CMD vs ENTRYPOINT

# CMD : commande par défaut (peut être écrasée)
CMD ["node", "server.js"]

# ENTRYPOINT : toujours exécutée (paramètre ajouté)
ENTRYPOINT ["node"]
CMD ["server.js"]

# ENTRYPOINT avec CMD par défaut
ENTRYPOINT ["python"]
CMD ["app.py"]

ENV vs ARG

# ENV : variable disponible dans le conteneur
ENV NODE_ENV=production
ENV DB_HOST=localhost

# ARG : variable disponible uniquement lors du build
ARG VERSION=1.0
RUN echo "Building version $VERSION"

EXPOSE

EXPOSE 3000                 # Documente le port (ne l'ouvre pas !)
EXPOSE 80/tcp              # Avec le protocole
EXPOSE 443                  # HTTPS

Note : EXPOSE ne fait qu'documenter. Vous devez quand même utiliser -p au docker run.


Dockerfile pour Node.js

FROM node:18-alpine

WORKDIR /app

# Dépendances d'abord (cache)
COPY package*.json ./
RUN npm ci --only=production

# Code source
COPY . .

# Port
EXPOSE 3000

# Démarrage
CMD ["node", "server.js"]

Dockerfile pour Python

FROM python:3.11-slim

WORKDIR /app

# Dépendances
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Code
COPY . .

EXPOSE 8000

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Dockerfile pour PHP/Laravel

FROM php:8.2-fpm-alpine

# Extensions nécessaires
RUN docker-php-ext-install pdo pdo_mysql mbstring

# Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

COPY . .
RUN composer install --no-dev --optimize-autoloader

EXPOSE 9000

CMD ["php-fpm"]

Bonnes pratiques

PratiqueMauvaisBon
Image de baseFROM ubuntuFROM node:18-alpine
Couches10 RUN séparés1-2 RUN combinés
CacheTout copier d'abordCopier package.json d'abord
SécuritéRoot par défautUSER node (non-root)
NettoyagePas de nettoyagerm -rf /var/lib/apt/lists/*

Exercices 🎯

  1. Dockerfile Node : Écrivez un Dockerfile pour une app Express.js.
  2. Dockerfile Python : Écrivez un Dockerfile pour une app Django.
  3. Multi-stage : Créez un Dockerfile multi-stage pour une app React (build + nginx).
  4. Optimisation : Comparez la taille de votre image avant et après optimisation.

Prochaine leçon : Docker Compose pour les applications multi-services.

⚡ Simulateur — Exécution d'un Dockerfile

Étape 1/7
📝 Pseudo-code
1FROM node:22-alpine
2WORKDIR /app
3COPY package*.json ./
4RUN npm ci --only=production
5COPY . .
6EXPOSE 3000
7CMD ["node", "server.js"]
🔍 Résultat de l'instruction
📥 FROM
base
node:22-alpine
taille
130MB
action
Image de base téléchargée

FROM : on part d'une image Node.js Alpine (130MB).