Compose : Docker, l’appli pour orchestrer les conteneurs

Compose facilite la mise à l’échelle et le déploiement d’applications dans Docker en automatisant la gestion de conteneurs. Dans ce tutoriel, nous allons voir en détail comment mettre en place et utiliser Docker Compose dans votre propre environnement de production.

Docker Compose, c’est quoi ?

Docker Compose sert à gérer les applications et augmente l’efficacité du développement de conteneurs. Les configurations sont définies dans un seul fichier YAML afin de faciliter la création et la mise à l’échelle des applications. Si on recourt souvent à Docker Compose pour mettre en place un environnement local, il peut également faire partie d’un flux de travail d’intégration continue / de livraison continue (CI/CD). Les personnes en charge du développement peuvent définir une version spécifique de conteneurs pour les tests ou pour une phase particulière du pipeline. De quoi faciliter l’identification des problèmes et la correction des bugs avant le passage en production proprement dite.

Docker Compose : les prérequis

Pour l’orchestration de conteneurs, vous avez besoin à la fois du Docker Engine et de Docker Compose. Vous devez donc avoir l’une des deux configurations suivantes :

  • soit Docker Engine et Docker Compose installés en tant que binaires autonomes ;
  • soit Docker Desktop en environnement de développement avec interface utilisateur graphique, qui inclut déjà le Docker Engine et Compose.
Conseil

Pour savoir comment installer Docker Compose sur d’autres systèmes d’exploitation, consultez nos tutoriels dédiés :

Utiliser Docker Compose étape par étape

Nous allons à présent expliquer les concepts de Docker Compose avec une simple application Web Python dont les appels seront comptabilisés. Nous allons pour cela utiliser le framework Python Flask et la base de données en mémoire Redis. Il n’est pas nécessaire d’installer Python ou Redis, car ils sont fournis sous forme d’images Docker.

Étape 1 : créer les fichiers du projet

Ouvrez le terminal et créez un nouveau dossier pour le projet.

$ mkdir composedemo
shell

Passez ensuite dans le répertoire.

$ cd composedemo
shell

Dans ce dossier, créez le fichier app.py et ajoutez-y le code suivant :

import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host=‘redis’, port=6379)
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr(‘hits’)
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)
@app.route(‘/’)
def hello():
    count = get_hit_count()
    return ‘Hello World! I was here {} times.\n’.format(count)
python

Nous utiliserons le nom d’hôte « Redis » et le port standard « 6379 ». De plus, nous indiquons que la fonction get_hit_count() devra faire plusieurs tentatives de connexion au service. Nous proposons ce processus car il se peut que Redis ne soit pas encore disponible au démarrage de l’application ou qu’il y ait des problèmes de connexion en cours d’exécution.

Créez enfin le fichier requirements.txt avec les dépendances :

flask
redis
plaintext

Étape 2 : configurer le dockerfile

Le dockerfile est utilisé pour l’image Docker. Il indique toutes les dépendances dont l’application Python a besoin.


FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
shell

Docker reçoit ainsi l’instruction d’utiliser l’image Python 3.7. De plus, nous avons défini les variables d’environnement pour la commande Flask. Avec apk add, nous installons gcc et d’autres dépendances. EXPOSE indique que le conteneur doit surveiller le port 5000. Avec COPY, le contenu du dossier actuel est copié dans le répertoire de travail /code. Comme commande standard pour le conteneur, nous choisissons flask run.

Vérifiez que le dockerfile a bien été enregistré sans extension de fichier, car certains éditeurs ajoutent automatiquement le suffixe .txt.

Étape 3 : créer le fichier YAML

Dans docker-compose.yml, nous configurons les services « redis » et « web ».

version: "3.9"
services:
    web:
        build: .
        ports:
            - "8000:5000"
    redis:
        image: "redis:alpine"
yaml

Le service Web utilise l’image créée par le dockerfile. Il associe le conteneur et l’ordinateur hôte au port 8000, tandis que le serveur Web Flask fonctionne sur le port 5000. En revanche, l’image Redis est simplement obtenue à partir du hub officiel de Docker.

Étape 4 : exécuter l’application avec Compose

Démarrez l’application à partir de votre dossier projet.

docker compose up
shell

Appelez http://localhost:8000 dans votre navigateur. Vous pouvez aussi saisir http://127.0.0.1:8000.

Vous devriez voir s’afficher le message suivant :

Application Docker Compose : sortie du nombre de visites dans le navigateur
Votre navigateur affiche le nombre de fois où vous avez consulté le site.

Actualisez la page. Le nombre de vues devrait maintenant avoir augmenté de 1.

Appeler à nouveau l’application Docker Compose
Le nombre de visites a augmenté de 1.

Vous pouvez arrêter l’application avec :

$ docker compose down
shell

Vous pouvez aussi appuyer sur Ctrl + C dans le terminal dans lequel vous avez lancé l’application.

Étape 5 : ajouter un Bind Mount

Si vous souhaitez ajouter un Bind Mount (ou mappage de répertoire) pour le service Web, vous pouvez le faire dans docker-compose.yml.

version: "3.9"
services:
    web:
        build: .
        ports:
            - "8000:5000"
        volumes:
            - .:/code
        environment:
            FLASK_DEBUG: "true"
    redis:
        image: "redis:alpine"
yaml

Sous Volumes, nous indiquons que le dossier projet actuel doit être rattaché au répertoire /code à l’intérieur du conteneur. Cela permet de modifier le code sans devoir recréer l’image. La variable d’environnement FLASK_DEBUG ordonne à flask run de s’exécuter en mode développement.

Étape 6 : recréer et exécuter l’application

Saisissez la commande suivante dans le terminal pour réinitialiser le fichier Compose :

docker compose up
shell

Étape 7 : mettre à jour l’application

Comme vous utilisez maintenant un mappage de répertoire pour votre application, vous pouvez modifier votre code et voir automatiquement les changements sans avoir à recréer l’image.

Écrivez un nouveau texte d’accueil dans app.py.

return ‘Hello from Docker! I was here {} times.\n’.format(count)
python

Actualisez votre navigateur pour voir si les modifications ont bien été prises en compte.

Application Docker Compose : modification du texte d’accueil
Le texte d’accueil dans l’application Python a été modifié.

Étape 8 : commandes supplémentaires

L’option --help affiche une liste de commandes disponibles pour Docker Compose :

docker compose --help
shell

Pour laisser Docker Compose s’exécuter en arrière-plan, ajoutez l’argument -d :

docker compose up -d
shell

Avec down, tous les conteneurs sont supprimés. L’option --volumes supprime aussi les volumes utilisés par le conteneur Redis.

docker compose down --volumes
shell
Conseil

Pour débuter avec Docker, retrouvez dans le Digital Guide un tutoriel Docker ainsi qu’un aperçu des commandes Docker.