À quoi ça sert?
Docker veut résoudre le problème du fait que certaines applications tournent sur certaines machines mais qui peuvent pas tourner sur d’autres machines parce qu’il y a des configurations différentes par exemple: différents systèmes d’exploitations.
Ce problème est très courant dans le monde du développement, car l’évolution des applications devient de plus en plus rapide, et quand une application est mise en production, ça peut arriver qu’elle ne va pas se comporter de la même manière qu’avant (dans la machine du développeur par exemple).
Alors comment rendre le fonctionnement des applications stables sur des environnements différents?
Docker utilise les conteneurs, une fonctionnalité native dans le Kernel Linux mais que docker a réussi à simplifié et à rendre accessible.
Comment ça fonctionne?
Pour résumer:
- On a le moteur qui tourne sur les machines qui s’occupe des conteneurs.
- On a l’image, l’application qui va tourner dans le conteneur.
- On a le Docker Hub d’où on va télécharger les images qu’on va rouler sur notre machine.
- On a le conteneur qui est une instance d’une image téléchargée du Docker Hub ou créée par nous même.
On va voir tout de suite comment ça fonctionne en ligne de commande
$ docker run hello-world
Comme on est très ambitieux,
avant de lancer la commande
$ docker run -it ubuntu bash
$ docker run [options] [image] [commande]
Comme son nom l’indique, est de faire tourner une image selon une option, dans notre cas :
-it
: pour rendre le conteneur interactif avec notre ligne de commande pour pouvoir interagir directement dedans.
ubuntu
: l’image Ubuntu.
bash
: l’argument supplémentaire pour spécifier que dans l’image ubuntu
on veut lancer l’application bash
qui est justement une application interactive.
On voit bien que avant j’étais dans l’utilisateur nas sur nas-XPS-15-9570 donc localement sur mon pc, maintenant je suis l’utilisateur root sur 8899aca61381 qui est un identifiant unique que docker a assigné au conteneur dans lequel je suis et qui est le hostname du conteneur.
Maintenant je retourne sur mon pc pour lancer la commande ps de docker qui est similaire à la commande ps
de linux pour voir les processus mais là pour voir les conteneurs qui tournent.
$ docker ps
On voit bien que notre conteneur ID 8899aca61381 contenant l’image ubuntu qui a lancé l’application bash.
On constate aussi que docker a assigné aussi un nom au hasard au conteneur pour les identifier plus facilement qu’avec des ID imprononçable.
Comme ça si je veux arrêter ce conteneur depuis ma machine, j’utilise la commande
$ docker stop 8899aca61381
Ou
$ docker stop nice_wescoff
et pour supprimer le conteneur
$ docker rm 8899aca61381
Ou
$ docker rm nice_wescoff
Maintenant que vous avez les bases, on va essayer de créer une image.
Comment créer une image Docker?
Pour créer notre propre image, nous allons créer un fichier nommé Dockerfile
dans lequel on va trouver l’ensemble de la recette qui décrit l’image Docker dont on aura besoin pour notre projet.
Jetons un coup d’œil sur le fichier Dockerfile
qui se trouve ici
FROM python:3.8.1-slim WORKDIR /app COPY . /app RUN pip install -r requirements.txt EXPOSE 80 ENV NOM Docker CMD ["python", "app/app.py"]
On veut créer une application web en python utilisant le module Flask pour le serveur et une base de données Redis
Pour expliquer le fichier Dockerfile
FROM
est un mot clé de Docker pour spécifié à partir de quelle image on va démarrer, c’est possible démarrer de 0, mais nous on va utiliser une image qui existe déjà, comme on va mettre en oeuvre une application python, donc on met python:version en occurrence 3.8.1-slim, pourquoi slim? pour une version beaucoup plus légère sans superflu que la version officielle.
WORKDIR
encore un mot clé pour dire à Docker dans quel répertoire effectuer les actions qui vont suivre, donc /app
est un dossier qui va être à la racine du conteneur, où on va copier notre application avec le mot clé COPY
.
pour copier directement le répertoire courant dans le répertoire /app
.
Une fois qu’on a fait ça, on va installer les dépendances de notre application qui se trouvent dans le fichier requirements.txt
qui sont justement Flask
et Redis
.
$ cat requirements.txt
Flask Redis
Avec la commande RUN pip install -r requirements.txt
, pour dire qu’une fois dans le conteneur, installe ces dépendances.
Puis en utilisant le mot clé EXPOSE
, on expose le port 80 par lequel on va accéder à l’application (au conteneur).
Le mot clé ENV
<key>
<value>
définira une variable d’environnement unique sur une valeur. La chaîne entière après le premier espace sera traitée comme la <value>
– y compris les caractères tels que les espaces et les guillemets.
Et finalement CMD
suivi d’une liste de chaînes de caractères ["python", "app/app.py"]
pour dire au conteneur de lancer la commande
$ python app/app.py
vous trouverez le code source de l’application ici.
Maintenant que vous avez tout compris sur le fichier Dockerfile
on va lancer cette commande pour construire notre image.
$ docker build [options] [path_to_dockerfile]
par exemple:
$ docker build -t monimage .
L’option -t
pour donner un nom à l’image par exemple monimage
.
On voit bien que l’image est créée, et tout les prérequis sont téléchargés. Maintenant on peut l’exécuter:
$ docker run -p 8080:80 monimage
$ docker ps
Et là aussi on peut voir que l’application tourne bien sur le conteneur b679ced8616e
Voilà on a bien notre application qui tourne dans un conteneur Docker, avec ça, on a plus besoin d’avoir python installé sur notre machine ni d’avoir de dépendances installées ni de s’embêter avec quelles versions l’application fonctionne, tout est dans le conteneur qu’on peut lancer sur n’importe quelle machine.
Mais il y a une erreur de connexion à la base de données Redis
.
Si vous êtes encore plus ambitieux, je vous invite à découvrir la solution pour cette erreur et comment orchestrer plusieurs conteneurs pour faire fonctionner une application complète.
Ping : Namespaces Linux et relation avec Docker – Sysblog
Ping : Docker-compose : comment faire fonctionner une application complète? – Sysblog