⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Démarrage rapide Docker Compose

Ce tutoriel vise à introduire les concepts fondamentaux de Docker Compose en vous guidant à travers le développement d'une application web Python basique.

En utilisant le framework Flask, l'application présente un compteur de visites dans Redis, fournissant un exemple pratique de comment Docker Compose peut être appliqué dans des scénarios de développement web.

Les concepts démontrés ici devraient être compréhensibles même si vous n'êtes pas familier avec Python.

Ceci est un exemple non-normatif qui démontre les fonctionnalités principales de Compose.

Prérequis

Assurez-vous d'avoir :

Étape 1 : Configuration

  1. Créez un répertoire pour le projet :

    $ mkdir composetest
    $ cd composetest
    
  2. Créez un fichier appelé app.py dans votre répertoire de projet et collez 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 f'Hello World! I have been seen {count} times.\n'

    Dans cet exemple, redis est le nom d'hôte du conteneur redis sur le réseau de l'application et le port par défaut, 6379 est utilisé.

    Note

    Notez la façon dont la fonction get_hit_count est écrite. Cette boucle de nouvelle tentative basique tente la requête plusieurs fois si le service Redis n'est pas disponible. Ceci est utile au démarrage pendant que l'application se met en ligne, mais rend aussi l'application plus résiliente si le service Redis doit être redémarré à tout moment pendant la durée de vie de l'app. Dans un cluster, cela aide aussi à gérer les déconnexions momentanées entre nœuds.

  3. Créez un autre fichier appelé requirements.txt dans votre répertoire de projet et collez le code suivant :

    flask
    redis
  4. Créez un Dockerfile et collez le code suivant :

    # syntax=docker/dockerfile:1
    FROM python:3.10-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", "--debug"]

    Ceci dit à Docker de :

    • Construire une image en commençant par l'image Python 3.10.
    • Définir le répertoire de travail à /code.
    • Définir les variables d'environnement utilisées par la commande flask.
    • Installer gcc et autres dépendances
    • Copier requirements.txt et installer les dépendances Python.
    • Ajouter des métadonnées à l'image pour décrire que le conteneur écoute sur le port 5000
    • Copier le répertoire actuel . dans le projet vers le répertoire de travail . dans l'image.
    • Définir la commande par défaut pour le conteneur à flask run --debug.
    Important

    Vérifiez que le Dockerfile n'a pas d'extension de fichier comme .txt. Certains éditeurs peuvent ajouter cette extension automatiquement ce qui résulte en une erreur quand vous exécutez l'application.

    Pour plus d'informations sur comment écrire des Dockerfiles, voir la référence Dockerfile.

Étape 2 : Définir les services dans un fichier Compose

Compose simplifie le contrôle de toute votre pile d'application, facilitant la gestion des services, réseaux et volumes dans un seul fichier de configuration YAML compréhensible.

Créez un fichier appelé compose.yaml dans votre répertoire de projet et collez ce qui suit :

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

Ce fichier Compose définit deux services : web et redis.

Le service web utilise une image qui est construite depuis le Dockerfile dans le répertoire actuel. Il lie ensuite le conteneur et la machine hôte au port exposé, 8000. Cet exemple de service utilise le port par défaut pour le serveur web Flask, 5000.

Le service redis utilise une image publique Redis tirée du registre Docker Hub.

Pour plus d'informations sur le fichier compose.yaml, voir Comment fonctionne Compose.

Étape 3 : Construire et exécuter votre app avec Compose

Avec une seule commande, vous créez et démarrez tous les services depuis votre fichier de configuration.

  1. Depuis votre répertoire de projet, démarrez votre application en exécutant docker compose up.

    $ docker compose up
    
    Creating network "composetest_default" with the default driver
    Creating composetest_web_1 ...
    Creating composetest_redis_1 ...
    Creating composetest_web_1
    Creating composetest_redis_1 ... done
    Attaching to composetest_web_1, composetest_redis_1
    web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
    redis_1  | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    redis_1  | 1:C 17 Aug 22:11:10.480 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started
    redis_1  | 1:C 17 Aug 22:11:10.480 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
    web_1    |  * Restarting with stat
    redis_1  | 1:M 17 Aug 22:11:10.483 * Running mode=standalone, port=6379.
    redis_1  | 1:M 17 Aug 22:11:10.483 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    web_1    |  * Debugger is active!
    redis_1  | 1:M 17 Aug 22:11:10.483 # Server initialized
    redis_1  | 1:M 17 Aug 22:11:10.483 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
    web_1    |  * Debugger PIN: 330-787-903
    redis_1  | 1:M 17 Aug 22:11:10.483 * Ready to accept connections
    

    Compose tire une image Redis, construit une image pour votre code, et démarre les services que vous avez définis. Dans ce cas, le code est statiquement copié dans l'image au moment de la construction.

  2. Entrez http://localhost:8000/ dans un navigateur pour voir l'application en cours d'exécution.

    Si cela ne fonctionne pas, vous pouvez aussi essayer http://127.0.0.1:8000.

    Vous devriez voir un message dans votre navigateur disant :

    Hello World! I have been seen 1 times.
    hello world dans le navigateur
  3. Actualisez la page.

    Le nombre devrait s'incrémenter.

    Hello World! I have been seen 2 times.
    hello world dans le navigateur

Étape 4 : Modifier le fichier Compose pour ajouter un montage de liaison

Modifiez le fichier compose.yaml dans votre répertoire de projet pour ajouter un montage de liaison pour le service web :

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

Le nouveau mot-clé volumes monte le répertoire du projet (répertoire actuel) sur l'hôte vers /code à l'intérieur du conteneur, vous permettant de modifier le code à la volée, sans avoir à reconstruire l'image. La clé environment définit la variable d'environnement FLASK_DEBUG, qui dit à flask run de s'exécuter en mode de développement et de recharger le code lors des changements. Ce mode ne devrait être utilisé qu'en développement.

Étape 5 : Reconstruire et exécuter l'app avec Compose

Depuis votre répertoire de projet, tapez docker compose up pour construire l'app avec le fichier Compose mis à jour, et l'exécuter.

$ docker compose up

Creating network "composetest_default" with the default driver
Creating composetest_web_1 ...
Creating composetest_redis_1 ...
Creating composetest_web_1
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
redis_1  | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
...

Vérifiez le message Hello World dans un navigateur web à nouveau, et actualisez pour voir le compte s'incrémenter.

Tip

Shared folders, volumes, and bind mounts

  • Si votre projet est en dehors du répertoire Users (cd ~), alors vous devez partager le lecteur ou l'emplacement du Dockerfile et du répertoire de volume avec Docker. Voir Partage de fichiers dans les paramètres Docker Desktop.

  • Si vous utilisez Oracle VirtualBox sur une machine Windows plus ancienne, vous pourriez rencontrer un problème avec les dossiers partagés comme décrit dans cette session stackoverflow VB. Des versions plus récentes de Docker Desktop pour Windows utilisent Hyper-V et n'ont pas ce problème.

Étape 6 : Mettre à jour l'application

Parce que le code d'application est maintenant monté dans le conteneur en utilisant un volume, vous pouvez faire des changements à son code et voir les changements instantanément, sans avoir à reconstruire l'image.

Changez le message d'accueil dans app.py et sauvegardez-le. Par exemple, changez le message Hello World! vers Hello depuis Docker! :

return f'Hello depuis Docker! I have been seen {count} times.\n'

Actualisez l'app dans votre navigateur. Le message d'accueil devrait être mis à jour, et le compteur devrait toujours s'incrémenter.

hello depuis docker dans le navigateur

Étape 7 : Expérimenter avec d'autres commandes

Si vous voulez exécuter vos services en arrière-plan, vous pouvez passer le drapeau -d (pour mode "détaché") à docker compose up et utiliser docker compose ps pour voir ce qui est actuellement en cours d'exécution :

$ docker compose up -d

Starting composetest_redis_1...
Starting composetest_web_1...

$ docker compose ps

       Name                      Command               State           Ports         
-------------------------------------------------------------------------------------
composetest_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp              
composetest_web_1     flask run                         Up      0.0.0.0:8000->5000/tcp

La commande docker compose run vous permet d'exécuter des commandes ponctuelles pour vos services. Par exemple, pour voir quelles variables d'environnement sont disponibles pour le service web :

$ docker compose run web env

Voir docker compose --help pour voir d'autres commandes disponibles.

Si vous avez démarré Compose avec docker compose up -d, arrêtez vos services une fois que vous avez terminé avec eux :

$ docker compose stop

Vous pouvez tout supprimer, en retirant complètement les conteneurs, avec la commande down. Passez --volumes pour aussi retirer le volume de données utilisé par le conteneur Redis :

$ docker compose down --volumes

À ce stade, vous avez vu les bases de comment fonctionne Compose.

Quelle est la suite ?