12. Déployer un Docker Compose multi-conteneurs - Docker
Nous n'avons pas fini d'explorer le réel intérêt de Docker Compose.
Nous avons jusqu'ici déployé un simple conteneur. Prenons maintenant le cas d'une architecture nécessitant plusieurs conteneurs, avec des dépendances entre eux, comme une application qui se connecte à une base de données par exemple.
Contexte
Dans le cas d'une architecture trois-tiers composée d'un applicatif se connectant à une base de données, chaque composant aura son propre conteneur.
Rappelons que la philosophie de Docker est de dire qu'un conteneur = un processus.
Il n'est pas envisageable de déployer toute cette architecture composant par composant, commande par commande.
C'est ici que Docker Compose intervient, pour déployer le tout en même temps.
Dans l'exemple qui va suivre, nous allons déployer un conteneur Flask (framework Python) connecté à un autre conteneur avec une base de données Redis.
Voici à quoi ressemble notre projet :
├── app.py
├── docker-compose.yml
├── Dockerfile
├── .env
└── requirements.txt
Le conteneur Flask
Inutile de détailler le code Flask, tout ce qu'il faut savoir c'est qu'il récupère le nombre de requêtes HTTP à la racine (/), affiche ce nombre et l'incrémente à chaque nouvelle requête.
L'objectif est d'afficher ceci dans notre navigateur :
Créons notre fichier app.py
contenant notre code Flask :
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
redis.incr('hits')
counter = str(redis.get('hits'),'utf-8')
return "Cette page a été consultée "+counter+" fois"
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
Comme nous voulons exécuter notre propre code dans le conteneur Flask, nous allons construire notre propre image Docker.
Pour ce faire, nous allons créer ce Dockerfile
:
FROM python:3.11
WORKDIR /app
COPY requirements.txt /app
RUN pip3 install -r requirements.txt --no-cache-dir
COPY . /app
CMD ["app.py"]
ENTRYPOINT ["python3"]
Vous l'avez vu ! L'instruction RUN
mentionne un certain fichier requirements.txt
que nous allons tout de suite créer (ce fichier sert à installer les modules Python nécessaires) comme ceci :
flask
redis
C'est tout pour notre conteneur Flask. Nous avons :
- Notre code
- Notre image Docker prête à être build
- Notre fichier
requirements.txt
contenant les dépendances de notre code à installer
Le Docker Compose
Pour le déploiement de nos deux services Flask et Redis à partir du fichier docker-compose.yml
, voici d'abord la composition de notre service Redis :
---
version: '3.3'
services:
redis:
image: bitnami/redis
container_name: redis
restart: unless-stopped
env_file: .env
Deux nouvelles clés entrent en jeu :
restart
: Cette clé applique une politique de redémarrage pour le conteneur en cas d'echec.
Ici, la valeurunless-stopped
indique que Docker va automatiquement essayer de relancer le conteneur en cas d'echec, sauf si le conteneur est arrêté manuellement.
Cette clé est l'équivalent de l'argument--restart
de la commandedocker run
env_file
: Désigne le fichier contenant les variables d'environnement. Nous verrons son contenu plus bas. Le fichier par défaut est nommé.env
. Il est donc possible d'omettre cette clé, sauf si le fichier est nommé différemment.
C'est l'équivalent de la cléenvironment
pour Docker Compose et de l'argument-e
de la commandedocker run
.
Pour la composition de notre service Flask, voici le bloc suivant :
flask:
build: .
container_name: flask
restart: unless-stopped
ports:
- "5000:5000"
volumes:
- app:/code
depends_on:
- redis
volumes:
app:
Les clés build
, ports
, volumes
etc... vous sont familières. Attardons-nous plus particulièrement sur celle-ci :
depends_on
: Définit l'ordre de démarrage des conteneurs. Dans notre cas le service Flask ne démarrera pas tant que le conteneur Redis ne sera pas démarré.
Comme dit plus haut, nous allons définir les variables d'environnement de nos conteneurs dans un fichier nommé .env
comme ceci :
ALLOW_EMPTY_PASSWORD=yes
Cette variable d'environnement est propre au conteneur Redis mais le contenu de ce fichier s'applique pour toute notre Docker Compose.
Voici à quoi ressemble le fichier docker-compose.yml
au complet :
---
version: '3.3'
services:
redis:
image: bitnami/redis
container_name: redis
restart: unless-stopped
env_file: .env
flask:
build: .
container_name: flask
restart: unless-stopped
ports:
- "5000:5000"
volumes:
- app:/code
depends_on:
- redis
volumes:
app:
Pour le déployer, il suffit d'exécuter la commande suivante :
docker-compose up -d
Il est possible de vérifier le statut des conteneurs avec la commande suivante :
docker-compose ps
C'est l'équivalent de la commande docker ps
mais avec une sortie différente.
Pour vérifier si notre projet a été déployé correctement, il suffit de se rendre sur son navigateur et d'accéder à http://localhost:5000
.
Maintenant que nous avons déployé plusieurs conteneurs simultanément, regardons dans le cours suivant comment les administrer.