Retour au cours

dockerfile : création d'images

Objectifs

  • Comprendre le rôle et la syntaxe d’un Dockerfile.
  • Utiliser les instructions de base : FROM, WORKDIR, COPY, RUN, et CMD.
  • Construire une image Docker personnalisée à partir d’un Dockerfile avec la commande docker build.
  • Connaître les bonnes pratiques pour créer des images légères et efficaces.

Qu’est-ce qu’un Dockerfile ?

Un Dockerfile est un fichier texte qui contient une série d’instructions, comme une recette de cuisine, que Docker suit pour construire une image. Chaque instruction crée une “couche” dans l’image. Cette approche en couches rend les builds efficaces, car Docker peut mettre en cache les couches qui n’ont pas changé.

Le fichier doit s’appeler Dockerfile (avec un D majuscule et sans extension).

Les instructions fondamentales

  • FROM : Définit l’image de base sur laquelle on construit. C’est toujours la première instruction. On part rarement de zéro ; on part d’une image officielle qui contient déjà un système d’exploitation ou un langage (ex: ubuntu:22.04, python:3.11-slim).

  • WORKDIR : Définit le répertoire de travail pour les instructions qui suivent (COPY, RUN, CMD). Si le dossier n’existe pas, il est créé. WORKDIR /app

  • COPY : Copie des fichiers ou des dossiers depuis votre machine locale (le “contexte de build”) vers le système de fichiers de l’image. COPY requirements.txt . (copie requirements.txt dans le WORKDIR, ici /app)

  • RUN : Exécute une commande pendant la construction de l’image. On l’utilise pour installer des paquets, des dépendances, etc. RUN pip install -r requirements.txt

  • CMD : Définit la commande par défaut à exécuter lorsque le conteneur est lancé. Il ne doit y avoir qu’une seule instruction CMD dans un Dockerfile. CMD ["python", "app.py"] (format “exec”, recommandé)

Exemple : Dockeriser une application Python simple

Fichier app.py :

print("Hello from Docker!")

Fichier Dockerfile :

# 1. Partir d'une image Python légère
FROM python:3.11-slim

# 2. Définir le répertoire de travail dans l'image
WORKDIR /app

# 3. Copier le code de l'application dans l'image
COPY app.py .

# 4. Définir la commande à exécuter au lancement
CMD ["python", "app.py"]

Construire et lancer l’image

  1. Construire l’image La commande docker build lit le Dockerfile et exécute les instructions.

    • -t mon-app:1.0 : “Tague” l’image avec un nom (mon-app) et une version (1.0).
    • . : Indique que le “contexte de build” (le dossier contenant le Dockerfile et les fichiers à copier) est le dossier courant.
    docker build -t mon-app:1.0 .
  2. Lancer un conteneur à partir de la nouvelle image

    docker run mon-app:1.0
    # Affiche : Hello from Docker!

Bonnes pratiques

  • Utilisez des images de base minimalistes : Au lieu de ubuntu (plusieurs centaines de Mo), préférez des images comme python:3.11-slim ou alpine. Elles sont beaucoup plus légères, ce qui accélère les téléchargements et réduit la surface d’attaque.
  • Tirez parti du cache de build : Ordonnez vos instructions des moins fréquentes aux plus fréquentes. Par exemple, copiez et installez vos dépendances (requirements.txt) avant de copier le code source de votre application. Ainsi, si vous ne changez que votre code, Docker n’aura pas à réinstaller les dépendances.
  • Utilisez un fichier .dockerignore : C’est comme un .gitignore. Il permet d’exclure des fichiers (comme le dossier .git, les environnements virtuels venv, etc.) du contexte de build pour ne pas les copier inutilement dans l’image.

Pièges courants

  • Confondre RUN et CMD : RUN s’exécute une seule fois, au moment du build. CMD s’exécute à chaque fois que vous faites docker run.
  • Images trop lourdes : Copier tout le dossier du projet avec COPY . . sans un .dockerignore est une erreur fréquente qui alourdit l’image.
  • Construire en tant que root : Par défaut, les commandes dans un Dockerfile s’exécutent en tant que root. Pour plus de sécurité, il est recommandé de créer un utilisateur non-privilégié (RUN useradd ... et USER ...).

Exercices

  1. Créez l’application :

    • Créez un dossier, et à l’intérieur, un fichier app.py avec le code de l’exemple ci-dessus.
  2. Écrivez le Dockerfile :

    • Dans le même dossier, créez un fichier Dockerfile et copiez-y le contenu de l’exemple.
  3. Construisez votre première image :

    • Exécutez docker build -t hello-docker:0.1 ..
    • Vérifiez que l’image a été créée avec docker images.
  4. Lancez votre conteneur :

    • Exécutez docker run hello-docker:0.1 et vérifiez que le message s’affiche bien.