Aller au contenu principal

Dockerfile

Maîtriser le Dockerfile pour la conteneurisation

Notions théoriques

Docker offre 3 méthodes pour créer des conteneurs :

  • utiliser une image existante,
  • ou construire votre propre image avec un Dockerfile,
  • ou utiliser Docker Compose pour des applications complexes.

Un Dockerfile, c’est un fichier texte qui contient une série d’instructions pour construire une image Docker.

astuce

Une image Docker, c’est une sorte de paquet tout prêt qui contient tout ce dont une application a besoin pour tourner (le code, les outils, les réglages).

info

Ensuite, avec cette image, tu peux créer des conteneurs, qui sont comme des petites machines virtuelles ultra-légères où ton application vit et travaille.

Voici les instructions essentielles à connaître pour écrire un bon Dockerfile :

  • FROM : C’est le point de départ, l’ingrédient de base.

    Par exemple, FROM ubuntu:20.04 dit qu’on commence avec une image d’Ubuntu version 20.04.

  • RUN : Là, tu donnes des ordres pour modifier l’image, comme installer des trucs.

    Exemple : RUN apt-get update && apt-get install -y python3 ajoute Python 3.

  • COPY : Ça te permet de prendre des fichiers de ton ordinateur et de les mettre dans l’image.

    Par exemple, COPY . /app copie tout ton projet dans le dossier /app de l’image.

  • WORKDIR : C’est comme dire "je vais travailler ici maintenant".

    Avec WORKDIR /app, toutes les commandes qui suivent se passent dans /app.

  • EXPOSE : Ça indique sur quel port ton application va "parler".

    Par exemple, EXPOSE 8080 signale que ton appli utilise le port 8080.

  • CMD : C’est la commande qui se lance quand ton conteneur démarre.

    Exemple : CMD ["python3", "app.py"] dit de lancer un fichier Python.

info

Pour transformer ton Dockerfile en image, tu utilises la commande docker build.

Par exemple, tape docker build -t mon-image . dans ton terminal, et hop, ton image est prête !

Quelques astuces de pro
  • Essaie de regrouper tes commandes RUN (comme RUN commande1 && commande2) pour que l’image reste légère.
  • Prends des images de base petites, comme alpine, si tu peux.
  • Nettoie derrière toi (supprime les fichiers temporaires) pour éviter que l’image devienne trop grosse.

Avec ça, tu as les bases pour créer des images Docker solides et efficaces !


Exemple pratique

Imaginons qu’on veut faire une image Docker pour une petite appli Web codée en Node.js.

Voici un Dockerfile simple et clair :

# On prend une image Node.js comme base
FROM node:14

# On choisit où travailler dans l’image
WORKDIR /app

# On copie le fichier des dépendances et on les installe
COPY package.json .
RUN npm install

# On ajoute tout le reste du projet
COPY . .

# On dit que l’appli utilise le port 3000
EXPOSE 3000

# On lance l’appli quand le conteneur démarre
CMD ["npm", "start"]

Comment ça marche ?

  1. FROM node:14 : On part d’une image officielle avec Node.js 14.
  2. WORKDIR /app : On se met dans le dossier /app pour la suite.
  3. COPY package.json . : On copie juste le fichier qui liste les dépendances.
  4. RUN npm install : On installe ces dépendances avec npm.
  5. COPY . . : On ajoute tout le reste du projet (code, etc.).
  6. EXPOSE 3000 : On précise que l’appli écoute sur le port 3000.
  7. CMD ["npm", "start"] : On dit à Docker de lancer l’appli avec npm start.
info

Pour tester, mets ce Dockerfile dans un dossier avec ton projet Node.js, puis tape docker build -t mon-app-node . dans ton terminal. Ton image est prête à être utilisée !

Test de mémorisation/compréhension


Quelle instruction choisit l’image de base ?


Quelle instruction exécute une commande pendant la construction ?


Comment copie-t-on des fichiers dans l’image ?


Quelle instruction fixe le dossier de travail ?


Quelle instruction montre quel port est utilisé ?


Quelle instruction lance l’appli au démarrage du conteneur ?


Quelle commande construit une image Docker ?


Quel est un bon conseil pour une image légère ?


Quelle instruction dans un Dockerfile garantit que toutes les commandes suivantes s’exécutent dans un répertoire spécifique de l’image ?


Pourquoi l’instruction EXPOSE dans un Dockerfile ne suffit-elle pas à elle seule pour rendre un port accessible depuis l’hôte ?


Pourquoi utilise-t-on python:3.9-slim plutôt que python:3.9 comme image de base ?


Quelle est la conséquence de ne pas regrouper plusieurs commandes RUN dans un seul RUN avec && dans un Dockerfile ?


Que se passe-t-il si une instruction CMD est omise dans un Dockerfile ?


Quelle commande Docker permet de vérifier que l’image mon-app-python a été créée avec succès après docker build ?


Dans l’exemple Node.js, que se passerait-il si on inversait les instructions COPY package.json et RUN npm install dans le Dockerfile ?



TP pour réfléchir et résoudre des problèmes

Créer et déployer une application Python avec Docker

Dans ce TP, vous allez :

  • construire une application Python simple,
  • la conteneuriser avec Docker,
  • et apprendre à gérer ses dépendances et son exécution.

Ce projet vous permettra de :

  • comprendre les bases de la création d’images Docker,
  • d’organiser un projet de manière professionnelle,
  • et de tester vos conteneurs localement.

1) Préparer l’environnement du projet

Pour commencer, vous allez mettre en place la structure de base de votre projet.

Cette étape est cruciale pour garder votre travail organisé et prêt pour la conteneurisation.

  1. Créer un dossier dédié au projet :

    • Ouvrez un terminal (sur Windows : CMD, PowerShell ou WSL ; sur Linux/Mac : terminal standard).
    • Exécutez la commande suivante pour créer un nouveau dossier :
      mkdir mon-projet-docker
    • Naviguez dans ce dossier avec :
      cd mon-projet-docker
    • Ce dossier sera la racine de votre projet et contiendra tous les fichiers nécessaires.
  2. Créer une application Python minimaliste :

    • Créez un fichier nommé app.py dans le dossier mon-projet-docker.

    Vous pouvez le faire via un éditeur de texte (comme VSCode, Sublime Text ou Notepad) ou directement dans le terminal avec :

    echo. > app.py  (Windows) ou touch app.py (Linux/Mac)
    • Ouvrez app.py avec votre éditeur préféré.
    • Ajoutez le code suivant :
      print("Bienvenue dans mon premier conteneur Docker !")
    • Ce programme affiche un message simple au démarrage. Sauvegardez le fichier.
  3. Vérifier l’organisation :

    • À ce stade, exécutez dir (Windows) ou ls (Linux/Mac) pour confirmer que votre dossier contient uniquement app.py. Une structure propre est essentielle pour éviter des erreurs lors de la construction de l’image Docker.
Une solution

2) Rédiger un Dockerfile fonctionnel

Le Dockerfile est le cœur de votre conteneur.

Il contient les instructions pour construire une image Docker qui exécutera votre application.

Dans cette partie, vous allez apprendre à structurer ce fichier avec des commandes essentielles.

  1. Créer le Dockerfile :

    • Dans le dossier mon-projet-docker, créez un fichier nommé Dockerfile (sans extension). Utilisez votre éditeur ou la commande :
      echo. > Dockerfile  (Windows) ou touch Dockerfile (Linux/Mac)
    • Ouvrez ce fichier pour commencer à le compléter.
  2. Spécifier une image de base :

    • Chaque Dockerfile commence par une image de base. Pour une application Python, utilisez python:3.9-slim, une version légère et optimisée de Python 3.9.
    • Ajoutez cette ligne au début du fichier :
      FROM python:3.9-slim
    • L’option slim réduit la taille de l’image par rapport à python:3.9, ce qui est une bonne pratique pour les projets simples.
  3. Définir un répertoire de travail :

    • Indiquez où les fichiers de votre application seront stockés dans le conteneur avec la commande WORKDIR. Utilisez /usr/src/app, un chemin conventionnel pour les applications.
    • Ajoutez :
      WORKDIR /usr/src/app
  4. Copier l’application dans l’image :

    • Utilisez la commande COPY pour transférer app.py de votre dossier local vers le répertoire de travail dans l’image.
    • Ajoutez :
      COPY app.py .
    • Le point (.) signifie "le répertoire courant défini par WORKDIR".
  5. Configurer la commande d’exécution :

    • La commande CMD définit ce qui se passe lorsque le conteneur démarre. Ici, vous voulez exécuter app.py avec Python.
    • Ajoutez :
      CMD ["python", "app.py"]
    • Le format liste (avec crochets) est recommandé pour éviter des problèmes d’interprétation par Docker.
Une solution

3) Construire et tester l’image Docker

Maintenant que votre Dockerfile est prêt, vous allez créer une image Docker et vérifier qu’elle fonctionne correctement en lançant un conteneur.

  1. Construire l’image Docker :

    • Assurez-vous d’être dans le dossier mon-projet-docker (utilisez cd mon-projet-docker si nécessaire).
    • Exécutez la commande suivante :
      docker build -t mon-app-python .
    • L’option -t donne un nom à l’image (mon-app-python), et le point (.) indique que le Dockerfile se trouve dans le répertoire courant.
    • Observez les étapes affichées dans le terminal : Docker télécharge l’image de base, copie les fichiers, et prépare l’image.
  2. Vérifier la création de l’image :

    • Listez les images disponibles sur votre système avec :
      docker images
    • Vous devriez voir mon-app-python avec une version latest dans la liste.
  3. Exécuter le conteneur :

    • Lancez un conteneur à partir de l’image avec :
      docker run mon-app-python
    • Si tout est correct, le message "Bienvenue dans mon premier conteneur Docker !" s’affichera dans le terminal, et le conteneur s’arrêtera automatiquement.
  4. Dépannage rapide :

    • Si rien ne s’affiche, vérifiez que app.py et le Dockerfile sont bien dans le dossier, et relancez la construction avec docker build.
Une solution

4) Enrichir l’application

Enrichir l’application avec des dépendances

Pour rendre le projet plus intéressant, vous allez ajouter une fonctionnalité utilisant une bibliothèque externe (requests) et adapter le Dockerfile en conséquence.

  1. Modifier l’application Python :

    • Ouvrez app.py et remplacez son contenu par :
      import requests
      response = requests.get("https://jsonplaceholder.typicode.com/todos/1")
      if response.status_code == 200:
      data = response.json()
      print(f"Tâche : {data['title']}, Terminée : {data['completed']}")
      else:
      print(f"Erreur : {response.status_code}")
    • Ce code effectue une requête HTTP à une API publique et affiche les détails d’une tâche.
  2. Créer un fichier de dépendances :

    • Créez un fichier nommé requirements.txt dans mon-projet-docker.
    • Ajoutez une ligne :
      requests
    • Ce fichier liste les bibliothèques nécessaires à votre application.
  3. Mettre à jour le Dockerfile :

    • Modifiez le Dockerfile pour inclure l’installation des dépendances avant d’exécuter l’application :
      FROM python:3.9-slim
      WORKDIR /usr/src/app
      COPY requirements.txt .
      RUN pip install --no-cache-dir -r requirements.txt
      COPY app.py .
      CMD ["python", "app.py"]
    • RUN pip install --no-cache-dir installe les dépendances sans conserver de fichiers temporaires, optimisant la taille de l’image.
  4. Reconstruire et tester :

    • Reconstruisez l’image avec :
      docker build -t mon-app-python .
    • Lancez le conteneur :
      docker run mon-app-python
    • Vous devriez voir un message comme "Tâche : delectus aut autem, Terminée : False" (les données exactes peuvent varier selon l’API).
Une solution