• 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 15/10/2024

Créez votre première image

Grâce aux éléments techniques que vous lui avez apporté et comme vous avez prouvé que vous pouviez lancer un conteneur, Liam a réussi à convaincre les investisseurs du bien-fondé du projet. Il est temps de commencer à intégrer l’application Libra dans un conteneur !

Intégrez votre propre service

Bien que de très nombreux services et applications soient déjà disponibles sur le Docker Hub (et souvent d’ailleurs directement intégrés par les équipes officielles des projets), il est courant de devoir réaliser sa propre image afin d’intégrer une application “maison” dans l’objectif de la déployer dans une infrastructure conteneurisée.

Vous allez découvrir dans ce chapitre comment sont structurées les images et surtout comment créer celles-ci vous-même !

Anatomie d’une image de conteneur

Les images Docker sont construites en “layers” (couche), où chaque layer représente une modification apportée à l'image.

Une image Docker est construite en layers, des couches correspondant à une modification apportée à l'image
Structure d'une image Docker

Pourquoi cette structure en couches ?

Les images Docker sont structurées en couches pour optimiser la réutilisation des données et accélérer la construction en utilisant le cache, ce qui permet de ne reconstruire que les couches modifiées. Cette structure modulaire permet :

  • de faciliter la mise à jour et la maintenance des images ;

  • d’améliorer l'isolation et la sécurité en séparant les étapes de construction ;

  • de simplifier le déploiement en permettant de partager et de transporter efficacement les images entre différents environnements.

Comprendre cette structure en couches est essentiel pour optimiser la construction et le déploiement des images Docker.

Une image est en général (mais pas obligatoirement) générée à partir d’un fichier appelé Dockerfile. Celui-ci contient une série d’instructions décrivant les opérations permettant la création de l’image.

Le Dockerfile est un fichier composé d'une série d'instructions décrivant les opérations à mener pour créer une image Docker
Structure d'un Dockerfile

Les instructions sont séparées en 2 grandes catégories:

  • Layering : Ces instructions (par exemple, RUN, COPY) créent un nouveau layer dans l'image et traduisent en général des opérations sur le système de fichier ou des commandes à exécuter sur celui-ci.

  • Metadata : Ces instructions (par exemple, EXPOSE, MAINTAINER, ENV) inscrivent des métadonnées qui seront associées à l’image, par exemple des informations telles que l’auteur, les ports exposés ou des variables d’environnement qui seraient disponibles dans le conteneur.

Et je peux générer une image à partir d’une simple archive ?

Tout à fait ! Il est également possible de générer une image directement à partir d’un fichier archive (plusieurs formats sont disponibles, par exemple TAR.GZ). L’image résultante sera alors constituée d’une seule couche.

Maintenant que vous connaissez la théorie derrière la structure des images Docker et comment celles-ci sont créées, il est temps pour vous de passer à la pratique !

Rédigez un Dockerfile

Un fichier Dockerfile est un simple fichier texte, constitué d’une suite d’instructions. Ces instructions peuvent globalement se répartir en deux grandes catégories :

  • Instructions de “construction” : elles permettent de définir, de manière directe ou indirecte, le contenu du système de fichiers du conteneur.

  • Instruction de “métadonnées” : elles permettent de renseigner des informations additionnelles qui seront associées à votre image et que les différents moteurs de conteneurisation pourront exploiter pour créer et exécuter des conteneurs.

Voyons ensemble un exemple de fichier et décortiquons ses différentes instructions :

# On s'appuie sur l'image ubuntu:22.04
FROM ubuntu:24.04
# Notre répertoire de travail
# sera la racine du système de fichier
# du conteneur
WORKDIR / 
# Notre image ne nécessite pas
# particulièrement de copier un fichier.
# Cependant, l'instruction suivante permettrait
# de copier le répertoire ./messages de la
# machine hôte vers le répertoire /data du conteneur
# COPY ./messages /data
RUN apt-get update && apt-get install -y cowsay dumb-init
# Définition d'une variable d'environnement
# "MESSAGE" avec en valeur par défaut "Mooo !!!"
ENV MESSAGE="Mooo !!!"
# Utilisation de l'utilitaire "dumb-init"
# comme point d'entrée de notre conteneur
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
# Définition de notre commande par défaut
CMD ["/bin/bash", "-c", "/usr/games/cowsay $MESSAGE"]
# Notre conteneur n'expose pas véritablement
# de service réseau, les instructions EXPOSE
# et VOLUMES n'ont donc pas de réelle utilité ici
# EXPOSE 80
# VOLUME /data
# Définition d'une étiquette arbitraire sur notre image
LABEL description="Un conteneur permettant d'afficher des messages humoristiques."

Instruction

Description

Exemple

`FROM`

Elle permet d'indiquer une image de "base" sur laquelle notre propre image s'appuiera. Notez qu'il est également possible de spécifier `FROM scratch` pour partir d'un système de fichier totalement vide si vous le souhaitez.

```(dockerfile)

FROM ubuntu:24.04 

```

`WORKDIR`

Elle permet de définir le répertoire courant. Celui-ci sera actif pour les instructions suivantes mais également comme répertoire courant par défaut lors de l'exécution du conteneur ! Une autre instruction, non utilisée dans ce Dockerfile, `USER` permet de définir l'utilisateur courant.

```(dockerfile)

WORKDIR /

```

`COPY`

Elle permet de copier un fichier de la machine hôte dans le futur système de fichier. Notez que les chemins relatifs seront toujours résolus depuis l'emplacement du fichier Dockerfile !

```(dockerfile)

COPY ./src /app

```

`RUN`

Elle permet d'exécuter une commande dans un environnement utilisant le système de fichier dans l'état associé à la couche courante. Vous pouvez par exemple utiliser cette instruction pour installer un paquet dans votre image.

```(dockerfile)

UN apt-get update && apt-get install -y cowsay dumb-init

```

`ENV` / `ARG`

Elles permettent de définir des variables d'environnement, accessibles à la phase d'exécution et à la phase de construction respectivement.

```(dockerfile)

ENV MESSAGE="Mooo !!!"

```

`ENTRYPOINT`/`CMD`

Elles fonctionnent souvent de pair.

La première permet de définir l'exécutable qui sera le point d'entrée de votre conteneur, le processus qui sera le parent de tous les autres. Ce processus a une grande responsabilité au sein d'un conteneur, il est donc souvent préférable de laisser ce rôle à des processus conçus pour assumer cette tâche, comme `tini` ou `dumb-init`, qui sont des systèmes d'init spécialisés pour des environnements conteneurisés.

L'instruction `CMD` quant à elle définit les arguments qui seront passés à l'exécutable définit par `ENTRYPOINT`. En général, l'instruction `CMD` définira l'application que vous souhaitez exécuter dans votre conteneur.

```(dockerfile)
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

CMD ["/bin/bash", "-c", "/usr/games/cowsay $MESSAGE"]
```

`EXPOSE`/`VOLUME`

Elles permettent ainsi de déclarer des ports potentiellement exposables par votre conteneur et des répertoires pouvant servir de point de montage pour des volumes. Notez cependant que ces informations sont purement indicatives et n'obligent en rien le moteur de conteneurisation à prendre des mesures automatiques pour respecter celles-ci !

```(dockerfile)

EXPOSE 80

VOLUME /data

```

`LABEL`

Elles permettent d'inscrire des étiquettes arbitraires sur votre image, sous forme de clé/valeur. Pour exemple, une description des fonctionnalités fournies par votre image.

```(dockerfile)

LABEL description="Un conteneur permettant d'afficher des messages via un avatar à quatres pattes."

```

Les Dockerfiles, c’est la plaie !

Ah oui, je comprends, la syntaxe des Dockerfiles vous donne des boutons. Chanceux que vous êtes, il existe une myriade d’autres outils permettant de construire des images Docker, ou pour être exact des images OCI. Ceux-ci adoptent parfois d’ailleurs des stratégies très différentes ! Par exemple, Buildah vous permet de générer des images d’une manière très proche à la rédaction de scripts shell.

Armé de l’ensemble de ces instructions et de notre Dockerfile fraîchement rédigé, nous pouvons maintenant lancer la construction de notre image !

Construisez votre image

Votre Dockerfile fraîchement rédigé, il est temps de découvrir comment le faire ingérer à Docker afin que celui-ci construise votre image ! C’est ce que nous allons voir dans la démonstration en vidéo suivante :

Dans cette vidéo nous avons vu comment :

  • construire une image Docker à partir d’un fichier Dockerfile via la commande docker builden spécifiant un nom d’image via le flag-t

  • appliquer des étiquettes à notre image afin de différencier nos différentes versions grâce à la commandedocker tag

  • gérer le registre local de nos images et gérer l’espace disque utilisé par celle-ci avec les sous commandesdocker images …

Vous avez l’ensemble des éléments permettant de construire une image personnalisée, attaquons nous maintenant à l’intégration de l’application Libra.

À vous de jouer

Contexte

Ce matin, à l’arrivée dans votre bureau vous trouvez une clé USB et un post-it sur votre clavier :

“PoC Libra”.

Neil, le développeur assigné au projet, n’a pas perdu de temps: vous savez à quoi votre journée sera dédiée !

L’application Libra se présente sous la forme d’un simple exécutable développé avec le langage Go et disponible sur ce dépôt Github

Votre objectif est de créer une image Docker contenant et exécutant l’application afin que celle-ci soit déployable avec Docker.

Consignes

Rédigez le Dockerfile permettant d’intégrer et d’exécuter l’application Libra sous forme conteneurisée

  • Baser votre image surubuntu:noble

  • Installer les dépendances nécessaires à la construction de l’image (paquetwget, qui servira au téléchargement de l’exécutable)

  • Télécharger l’archive contenant l’exécutable correspondant à votre architecture via ce lien avec la commandewget

  • Utiliser l’instructionCMDpour exécuter l’exécutable de l’application Libra dans le conteneur

En résumé

  • Les images Docker sont construites en couches, permettant la réutilisation des données et l'efficacité du cache.

  • Le Dockerfile définit les instructions pour construire une image, incluant des commandes commeFROM,COPY,RUN, etCMD.

  • La commande docker build crée une image à partir du Dockerfile, avec des options pour personnaliser la construction et appliquer des étiquettes.

Vous voici parvenu au terme de cette première partie. Avant de vous lancer dans le déploiement de l’application dans la partie suivante, je vous invite à évaluer vos connaissances dans le quiz juste après.

Exemple de certificat de réussite
Exemple de certificat de réussite