Mettre en application vos applications avec Docker

Cet article introduit les bases de Docker, explique comment créer une image Docker pour une application Streamlit, et utilise Docker Compose pour créer un site WordPress lié à une base de données MySQL. Il présente également les commandes pour créer, démarrer, arrêter et supprimer des conteneurs.

Paul Dauriac Profile Picture
Paul Dauriac Data Scientist

Introduction

L’objectif de ce tutoriel est d’introduire les bases de Docker. Pour cela nous allons découvrir pas à pas les commandes de bases nous permettant de mettre en production une application Streamlit. Puis nous allons utiliser Docker Compose afin de créer un site WordPress en liant celui-ci à une base de données MySQL.
Ce tutoriel s’adresse principalement à des programmeurs souhaitant découvrir Docker mais reste accessible au commun des mortels.

 

Docker est un outil permettant de lancer et partager une application facilement, rapidement et sur n’importe quel système d’exploitation classique (Windows, Linux, Mac et les serveurs). Pour faire cela, il se base sur le principe d’image et de conteneur.
L’objectif d’un conteneur est le même que pour une machine virtuelle: héberger des services (des applications) sur un même serveur physique tout en les isolant les uns des autres. Un conteneur est cependant moins figé qu’une machine virtuelle en matière de taille de disque et de ressources allouées mais cela aux dépens d’une isolation un peu moindre.

Même si chaque conteneur est isolé, il est possible de les faire communiquer entre eux à l’aide de réseaux virtuels. Cela permet par exemple de lier le conteneur contenant votre application au conteneur contenant votre base de données.
Si vous souhaitez installer Docker, vous pouvez le faire depuis le site Docker. Si vous ne pouvez pas installer Docker (il faut les droits administrateurs) ou si vous souhaitez faire un essai rapide, la plateforme Play with Docker permet de découvrir cet outil en ligne.

 

Créer et lancer une image

 

Pour créer une image, il faut tout d’abord choisir l’image sur laquelle va se baser notre application. Vous pouvez explorer les images disponibles sur Docker Hub. En Data Science, nous utilisons régulièrement l’image Python. C’est celle que nous utiliserons pour la suite de cette partie.
Nous allons créer une image docker permettant de lancer une application Streamlit en Python. Notre application contiendra les fichiers suivants:

    • requirements.txt -> Celui-ci doit contenir les packages nécessaires. Ici, au minimum Streamlit.
    • my_app.py -> Notre application Streamlit. Si vous avez besoin d’un exemple d’application, vous pouvez déployer la cheatsheet Streamlit.
    • Dockerfile -> Fichier de configuration de Docker. Nous allons le créer.

Dockerfile

 

Le Dockerfile est le fichier que Docker va utiliser pour avoir ses instructions. Dans le cas de notre application Streamlit, il faudra spécifier dans le Dockerfile les éléments suivants:

    • L’image de base à utiliser. Dans notre cas nous utiliserons Python 3.10 alpine
    • Le port que le conteneur va écouter lors de son exécution. Ici le port 8501
    • Workdir qui permet de modifier le répertoire courant. La commande est équivalente à une commande « cd » en ligne de commande. L’ensemble des commandes qui suivront seront toutes exécutées depuis le répertoire défini.
    • On copie le requirements.txt présent dans notre application dans le conteneur avec la commande “COPY
    • Une fois copié dans le conteneur, on exécute la commande “pip install – r requirements.txt” qui permet d’installer toutes les librairies présentes dans le fichier requirements.txt. Pour faire cela on utilise la commande “RUN
    • Une fois les librairies installées, on copie le reste de l’application dans le conteneur à l’aide de “COPY.
    • Enfin, on exécute  la commande “streamlit run my_app.py” avec “CMD”. Celle-ci permet de démarrer notre application Streamlit dans le conteneur.

Ceci donne le Dockerfile suivant:

 

FROM python:3.10alpine

EXPOSE 8501

WORKDIR /app

COPY requirements.txt ./requirements.txt

RUN pip3 install r requirements.txt

COPY . .

CMD streamlit run my_app.py

 

Il est important de comprendre la différence entre RUN et CMD:

    • RUN est une étape de construction de l’image. L’état du conteneur après une commande RUN sera intégré à l’image du conteneur. Un fichier Docker peut comporter de nombreuses étapes RUN qui se superposent les unes aux autres pour construire l’image.
    • CMD est la commande que le conteneur exécute par défaut lorsque vous lancez l’image construite. Un Dockerfile n’utilisera que la dernière CMD définie.

Créer son image avec Docker Build

Une fois notre Dockerfile créé, nous devons construire l’image. Pour faire cela, il suffit d’utiliser la commande suivante:

« docker build -t streamlit_app . »

L’option “-t” permet d’ajouter le tag streamlit_app à notre image. Faites bien attention au « . » à la fin de la commande. Il permet de spécifier que l’on souhaite utiliser le répertoire courant pour notre application

Démarrer un conteneur avec Docker run

Maintenant que notre image a été construite, nous pouvons la démarrer. Pour faire cela, nous utilisons la commande suivante:

« docker run -dp 8501:8501 streamlit_app »

L’option -d permet de lancer le conteneur en mode détaché (en background). L’option -p permet de spécifier le port d’entrée et de sortie. On retrouve la valeur que nous avons indiquée dans le Dockerfile.

NB: Si vous voulez directement lancer une image qui est publiée sur Docker Hub, vous n’avez pas besoin de créer un Dockerfile et de lancer de commande Docker build. Par exemple, si la mascotte du langage go vous donne envie d’essayer ce langage, vous pouvez utiliser la commande « docker run golang ». Celle-ci démarrera une interface de commande .

 

Lister, stopper et supprimer des images

 

Lister les conteneurs avec docker ps

 

Vous pouvez lister les conteneurs actifs avec la commande « docker ps »

Dans l’exemple ci-dessous, nous avons un conteneur docker/getting-started en cours et l’output de cette commande devrait retourner quelque chose ressemblant à cela: 

 

CONTAINER ID IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES
969f65bcecb2  docker/getting-started « nginx -g ‘… » 8 seconds ago Up 7 seconds 80/tcp… stupefied_davinci

 

Pour lister les conteneurs qui ont été stoppés, vous pouvez ajouter l’argument -a.

NB: Le nom d’un conteneur est défini lors de sa création avec l’option –name. Si celui-ci n’est pas donné, un nom aléatoire est généré.

 

Stopper un conteneur en cours d’exécution avec docker stop

Pour arrêter un conteneur mais sans le supprimer, il faut utiliser la commande docker stop. Celle-ci prend en argument l’ID ou le nom du conteneur. Par exemple, pour stopper le conteneur de la section précédente, vous pouvez utiliser une de ces deux commandes:

    • docker stop 969f65bcecb2
    • docker stop stupefied_davinci

Supprimer un conteneur avec docker rm

Une fois un conteneur arrêté, il est possible de le supprimer avec la commande docker rm. Celle-ci fonctionne comme docker stop.

Si vous souhaitez arrêter et supprimer un conteneur avec une seule commande, vous pouvez utiliser l’option -f. Par exemple:

    • docker rm -f 969f65bcecb2
    • docker rm -f stupefied_davinci

Docker Compose

 

Compose est un outil permettant de définir et de lancer plusieurs conteneurs à la fois. Le plus sorcier des lecteurs pourrait demander « Mais dis-moi Jamy, les conteneurs sont censés être isolés les uns des autres. Comment peuvent-ils donc communiquer? ». Eh bien mon cher lecteur, c’est grâce au principe de Networking (ou mise en réseau). 

Pour faire simple, si on a informé Docker que deux conteneurs appartiennent au même réseau, alors ils peuvent communiquer. Sinon, ils ne peuvent pas. Cela permet de garder nos conteneurs totalement isolés sauf lorsque c’est nécessaire. Vous trouverez une explication plus détaillée sur le tutoriel de Docker.

Il est possible de définir et lancer plusieurs conteneurs à la fois avec les commandes « classiques » de Docker mais cela est plus laborieux et prend plus de temps. Le tutoriel getting started (partie 5 à 7) créé par Docker couvre ce sujet.

Une alternative plus rapide, et que nous recommandons, est d’utiliser Docker Compose, qui se base sur un fichier au format YAML.

L’utilisation de Compose est constituée de 3 étapes:

    1. Création du Dockerfile comme vu plus tôt
    2. Création du fichier docker-compose.yaml
    3. Lancer les conteneurs avec `docker compose up`

Créer un fichier docker-compose.yaml est simple mais cela dépend de ce que vous voulez faire.. De manière générale, un fichier docker-compose doit contenir les éléments suivants:

    • La version de docker-compose. Dans l’exemple ci-dessous on utilise la version “3”
    • La liste de services (ou liste de containeur). Dans notre cas, on a le service « db » et le service « wordpress ». Dans chacun des services, on va définir tous les éléments qui peuvent être utiles comme l’image, le port, les variables d’environnements pour ce conteneur, les volumes qu’il va utiliser, etc. Évidemment cela varie selon l’image que l’on veut faire.
    • Les volumes qu’on doit utiliser (la base de données). Ici, db_data fait référence à la base de données MySQL.

Après la théorie, place à la pratique avec un exemple qui permettrait de déployer un site WordPress utilisant une base de données mySQL. Pour réaliser cela, un docker-compose possible est le suivant:

version: 3

services:

 db:

   image: mysql:5.7

   volumes:

     – db_data:/var/lib/mysql

   restart: always

   environment:

     MYSQL_ROOT_PASSWORD: somewordpress

     MYSQL_DATABASE: wordpress

     MYSQL_USER: wordpress

     MYSQL_PASSWORD: wordpress

 wordpress:

   depends_on:

     – db

   image: wordpress:latest

   ports:

     – « 8000:80« 

   restart: always

   environment:

     WORDPRESS_DB_HOST: db:3306

     WORDPRESS_DB_USER: wordpress

     WORDPRESS_DB_PASSWORD: wordpress

     WORDPRESS_DB_NAME: wordpress

volumes:

 db_data: {}

Vous trouverez plus de détails concernant les lignes de ce fichier sur la formation OpenClassrooms.

Il est important de noter que docker compose est préinstallé sur Windows, Mac et Play with Docker mais ce n’est pas le cas sur Linux. Si besoin, il existe un manuel d’installation.

 

Partager son image sur Docker Hub

 

Docker permet de facilement héberger ses images sur son hub afin de les partager à d’autres personnes. Pour faire cela, il faut:

  1. S’inscrire / se connecter sur le site Docker Hub
  2. Appuyer sur le bouton « Create Repository »
  3. Donner un nom à votre image et laisser la visibilité en « Public ». Pour la suite de l’exemple, nous donnerons le nom « repo_sur_docker_hub ». Dans sa version gratuite, Docker permet d’avoir un répertoire privé
  4. Appuyer sur le bouton « Create »
  5. Sur le terminal contenant l’image à publier (ici « mon_image »), utilisez les commandes suivantes:
      • docker tag mon_image NOM_D_UTILISATEUR/repo_sur_docker_hub
      • docker push NOM_D_UTILISATEUR/repo_sur_docker_hub

Si tout s’est bien passé, votre image est publiée sur Docker Hub. Vous pouvez la récupérer en utilisant la commande suivante:

« docker run -dp 3000:3000 NOM_D_UTILISATEUR/repo_sur_docker_hub »

 

Pour aller plus loin…

 

Une fois Docker maîtrisé, il existe d’autres outils tels que Kubernetes ou Ansible qui peuvent vous permettre d’améliorer vos solutions.

En effet, si une fois déployée, votre application rencontre un franc succès, l’augmentation du nombre d’utilisateurs peut rapidement poser  problème. En effet, vous risquez de faire face à deux situations :

    • Lors de la mise à jour de votre application, vous ne souhaitez pas avoir d’interruptions de services. Imaginez si votre boîte mail était inaccessible lors de la mise à jour.
    • Si votre application a en moyenne 1000 visites par heure mais un pic de 10000  visiteurs à 20h, cela pourrait poser un problème car l’architecture ne pourrait pas répondre à une telle demande.

 

L’utilisation de Kubernetes et/ou Ansible peut être une solution pour répondre à ces soucis. En plus de vous offrir de la flexibilité, une bonne utilisation de ces outils vous permettra de réduire le coût de votre architecture.

 

 

A voir absolument

Les articles les plus appréciés

Vous avez un projet de transfomation ? Parlons-en !