Skip to main content

Construction d'image avec Dockerfile

Dockerfile et layers

Les images Docker fonctionnent par couches successives d'instructions, les layers.

Un Dockerfile est un fichier texte qui décrit les différentes couches d'une image Docker.

Chaque couche permet d'ajouter des actions à l'image, par exemple :

  • Installation de dépendances
  • Configuration d'un environnement
  • Copie de fichiers depuis la machine hôte
  • Définition de la commande lancée au démarrage du conteneur
  • Etc.

Le dockerfile est comparable à une recette de cuisine : chaque instruction du Dockerfile représente une étape dans la préparation de l’environnement logiciel souhaité.

Son utilisation offre certains avantages :

  • Automatisation : chaque build est reproductible et scripté.
  • Traçabilité : le fichier peut être versionné avec Git.
  • Portabilité : un Dockerfile peut être utilisé sur n'importe quelle machine.
  • Modularité : il permet de construire des images à partir d’autres images, facilitant la réutilisation.

Ci-dessous un exemple de Dockerfile :

FROM debian:trixie # point de départ : une image existante
RUN apt-get update -y # commande à éxécuter
RUN apt-get install fastfetch -y # une autre commande, pour une nouvelle couche
ENTRYPOINT ["fastfetch"] # point d'entrée au lancement du conteneur

Les instructions d'un Dockerfile

N'hésitez pas à consulter la documentation de Docker à ce sujet : 🔗 Dockerfile reference.

FROM - Définir l'image de base

FROM ubuntu:24.04

C'est le point de départ de l'image :  une autre image de base officielle ou personnalisée.

LABEL - Ajouter des métadonnées

LABEL Maintainer="Thibaud FRICHET"
LABEL Description="Description de l'image"

Les métadonnées de l'image s'affichent avec docker image inspect.

WORKDIR - Définir le répertoire de travail

WORKDIR /var/www/html

Les instructions RUN, CMD et ENTRYPOINT s’exécutent dans le répertoire de travail.

COPY - Copier des fichiers locaux dans l'image

# copie fichier.txt à partir du répertoire courant de la machine hôte
# dans le répertoire courant de l'image (défini avec WORKDIR)
COPY fichier.txt ./ 

# copie le répertoire sources depuis la machine hôte vers le répertoire /var/www de l'image
COPY /home/thibaud/projet/sources/ /var/www/

RUN - Exécuter des commandes pendant la construction

# installation et lancement de Redis
RUN apt-get update -y
RUN apt-get install redis-server -y
RUN service redis-server start

Les commandes RUN s’exécutent pendant la construction de l'image, pas au démarrage d'un conteneur.

Les commandes doivent se terminer sans saisie utilisateur.

EXPOSE - Indiquer les ports utilisés par l'application
EXPOSE 80
EXPOSE 443

Ce sont les ports d'écoute du conteneur, ils peuvent être redirigés avec docker run -p 90:80 à l'exécution.

CMD - Définir les commandes par défaut à exécuter

L'instruction CMD accepte un tableau en paramètre.

CMD ["date", "echo Bonjour"] # affiche la date courante, puis "Bonjour"

Contrairement à RUN, l'instruction CMD est exécutée au démarrage du conteneur, pas pendant la construction.

ENTRYPOINT - Définir le point d'entrée du conteneur
ENTRYPOINT ["service nginx start"] # lance le serveur web nginx

CMD et ENTRYPOINT définissent  les commandes exécutées au démarrage d'un conteneur, mais avec un comportement différent :

  • CMD indique la commande avec des arguments par défaut qui peuvent être remplacés lors de l’exécution avec docker run.
  • ENTRYPOINT fixe le point d’entrée du conteneur, rendant son comportement plus rigide.

Lorsqu’ils sont utilisés ensemble, ENTRYPOINT définit le programme à exécuter et CMD les arguments par défaut. 

Dans la majorité des cas, vous pouvez utiliser l'un ou l'autre uniquement.

Bonnes pratiques

  • Utilisez des images légères. Exemples : python:3.10-slim, nginx-stable-alpine, etc.

  • Utilisez des versions fixes dans vos dépendances. Évitez les tags -latest par exemple.

  • Minimisez le nombre de couches, par exemple avec plusieurs commandes sur une ligne RUN et &&.
    RUN apt-get update -y && apt-get install redis-server
  • Utilisez .dockerignore pour exclure les fichiers inutiles, de la même manière qu'un .gitignore.
    Le contenu du répertoire courant de la machine hôte est envoyé à Docker lors de la construction d'une image. Docker appelle cela le context.

  • Respectez la convention de nommage d'un dockerfile :
    • Par défaut : Dockerfile
    • Avec un préfixe : dev.Dockerfile, prod.Dockerfile, app-v3.Dockerfile

La construction de l'image

La construction d'une image docker s'effectue avec docker build.

Le paramètre -t, --tag indique le nom de l'image et sa version. Le paramètre -f, --file le nom du fichier dockerfile, par défaut Dockerfile.

Un répertoire de contexte doit être indiqué, par exemple le répertoire courant avec ..

docker build -t mon_appli:1.0.0 -f monappli.Dockerfile .

image.png

image.png

Par la suite, une image Docker peut être exportée dans un fichier ou uploadée sur un registre privé par exemple.