Link Search Menu Expand Document

TP Docker n°2 - Découverte des Dockerfile

Dans ce TP nous aborderons une notion primoridale de Docker : la configuration d’une image grâce au Dockerfile.
Je n’aborderait pas toutes les subtilités du Dockerfile donc je vous invite à parcourir la documentation officielle tout au long de ce TP pour en découvrir d’avantage.


Sommaire


1. Introduction au Dockerfile

Un Dockerfile est comme son nom l’indique un fichier utilisé par Docker pour générer une image.
Docker lit les instructions de ce fichier et construit notre image personnalisée grâceà la commande :

docker build -t NOM_IMAGE CHEMIN_DOCKERFILE

De là nous pouvons utiliser cette image pour créer nos conteneurs.


2. Utilisation d’une image pré-existante

Tout comme avec la commande docker run, on peut utiliser une image disponible sur le Docker Hub pour nous faciliter le travail.
Pour cela il suffit de :

Télécharger le projet https://github.com/guillaume-elambert/stage-docker.


Se placer dans le dossier “encode-explorer” et supprimer le contenu du fichier nommé “Dockerfile”.


Saisir le contenu suivant dans le Dockerfile.

FROM image

Donc dans notre cas

FROM php:apache

Jusqu’ici nous pouvons déduire que le résultat sera le même qu’avec la commande vue dans le TP précédent. Pour rappel elle permet de créer un conteneur où Apache et PHP sont installés mais où il n’y ni contenu ni configuration pour le serveur Apache.

docker run php:apache

Construire l’image grâce au Dockerfile.

Solution

En admettant que vous vous trouvez dans le dossier “encode-explorer”, la commande pour construire l’image est :

# On créé l'image nommée "encode-explorer" à partir du Dockerfile contenu dans le fichier courrant
$ docker build -t encode-explorer .


Créer le conteneur basé sur l’image créée.

Solution

La commande pour créer le conteneur basé sur notre image “encode-explorer” est :

$ docker run encode-explorer


3. Définir des ports

Pour rappel nous avons vu que le conteneur Apache à besoin que nous lui fournissions un port.
Nous le faisions avec la commande :

docker run -p 8080:80 php:apache

Ainsi nous obtenions un conteneur configuré avec notre serveur Apache et nous pouvions y accéder via http://localhost:8080/.

Le Dockerfile ne permet pas se passer de l'option `-p PORT_HOTE:PORT_CONTENEUR` mais seulement de signaler que le conteneur à besoin que nous lui attribuions un port. Cette partie sert donc de documentation pour les utilisateurs.
Pour cela nous remplaçons le contenu de notre Dockerfile par :

FROM php:apache
EXPOSE 80

Comme vous pouvez le constater il n’est question ici que d’un seul port.
En effet on ne définit dans le Dockerfile que le port du conteneur que l’on ouvre. Ainsi les utilisateurs sont libres de choisir quel port de leur machine sera lié au port 80 du conteneur.


Donc il sera **toujours** nécessaire de spécifier l’option -p PORT_HOTE:PORT_CONTENEUR mais l’utilisateur peut consulter la liste des ports dont le conteneur à besoin et choisir librement comment il les réparti sur sa machine.
Je vous invite à consulter la documentation officielle pour de plus amples informations.


4. Copier des fichiers dans le conteneur

Dans le TP précédent nous avions réussi à créer la page d’accueil de notre serveur en “bidouillant” une commande à exécuter lors du lancement de notre conteneur :

# On créé un conteneur Apache avec PHP
# On définit le fait que le port 8080 de notre machine sera lié au port 80 du conteneur
# On passe une commande au conteneur qui :
#   1- Lance bash et exécute la chaîne de caractère comme une commande
#   2- Écrit "Hello World ! <?php phpinfo(); ?>" dans le fichier /var/www/html/index.php du conteneur
#   3- Lance Apache
docker run -d -p 8080:80 php:apache bash -c "echo \"Hello World ! <?php phpinfo(); ?>\" > index.php; apache2-foreground"

Le problème ici est que, en plus d’être très barbare, cette manière de faire ne permet pas de copier ou créer facilement tout un projet dans le conteneur.
Pour pallier cela, le Dockerfile peut contenir l’instruction COPY.
Ainsi pour copier le contenu d’un dossier “/chemin/vers/mon/dossier/source” on obtient le Dockerfile suivant :

FROM php:apache
EXPOSE 80
COPY /chemin/vers/mon/dossier/source destination/dans/le/conteneur

Dans notre cas :

FROM php:apache
EXPOSE 80
COPY /chemin/vers/le/dossier/encode-explorer /var/www/html

Ou avec des chemins relatifs. Si le fichiers Dockerfile se trouve dans le dossier “encode-explorer”, on obtient :

FROM php:apache
EXPOSE 80
COPY . .

Note :

Le premier point est le chemin vers le dossier courrant.
Le second correspond au dossier /var/www/html. En effet l’image php:apache définit le point de départ du conteneur comme étant /var/www/html. Ainsi toutes les commandes que nous lui passons sont effectuées relativement à ce dossier.
Pour plus d’informations, se renseigner sur l’instruction WORKDIR et observer le contenu du Dockerfile de l’image php:apache.



Supprimer tous les conteneurs grâce à la commande suivante.

# Supprime l'ensemble des conteneurs
$ docker rm `docker ps -aq`


Construire l’image grâce au Dockerfile puis créer un nouveau conteneur que vous nommerez “encode-explorer” basé sur celle-ci.

Solution

En admettant que vous vous trouvez dans le dossier “encode-explorer” les commandes sont :

# On créé l'image nommée "encode-explorer" à partir du Dockerfile contenu dans le fichier courrant
$ docker build -t encode-explorer .

# Cette commande permet de créer un conteneur basé sur l'image "encode-explorer".
# On lit le port 8080 de notre machine avec le port 80 du conteneur.
# On lui donne le nom "encode-explorer".
# Le nommage des conteneurs permet de faciliter leur manipulation.
$ docker run -p 8080:80 encode-explorer --name encode-explorer


⚠️  ATTENTION  ⚠️
Pour rappel il est toujours nécessaire de spécifier l’attribution de port lors de la création du conteneur, même si nous l’avons spécifier dans le Dockerfile.
Ne pas oublier !


Vérifier que nous avons bien les fichiers dans notre conteneur.

Pour cela il faut utiliser la commande docker exec (voir la documentation officielle ou docker exec --help).
Plusieurs options s’offrent à nous pour vérifier que nous obtenons bien le résultat escompté :

  1. Nous spécifions une commande pour lister les fichiers telle que ls
  2. Nous spécifions une commande qui nous permet de rentrer dans le conteneur et de le manipuler grâce à un terminal.


Pour la première solution on utilise la commande :

# On exécute la commande "ls -l" sur le conteneur nommé "encode-explorer".
# L'option "-t" permet de retourner visuellement le résultat de la commande.
$ docker exec -t encode-explorer ls -l


Pour la seconde solution :

# On exécute la commande "bash" sur le conteneur nommé "encode-explorer" (c.à.d qu'on lance un terminal).
# L'option "-i" permet de définir que nous allons interagir avec le conteneur (ici via le terminal bash).
# L'option "-t" permet de retourner visuellement le résultat des commandes passées au sein du conteneur.
$ docker exec -i -t encode-explorer bash

# Un terminal se lance.
# Vous remarquerez que comme vous êtes dans le conteneur vous avez des identifiants différents.
# Vous remarquerez également que nous sommes bien dans le dossiers /var/www/html comme vu un peu plus haut.

# On peut désormait lancer notre commande "ls -l"
root@e071acc58f08:/var/www/html$ ls -l

# Puis on sort du conteneur grâce à la commande "exit"
root@e071acc58f08:/var/www/html$ exit


Après avoir réalisé l’une des deux solutions présentées nous pouvons constater que nous obtenons bel et bien un conteneur qui contient les fichiers de notre dossier “encode-explorer”.