
Lors des laboratoires précédents, nous avons démarré des conteneurs à partir de la ligne de commande, c-a-d, en utilisant le cli de docker. Nous avons précédé ainsi car les paramètres de configuration étaient simples ou que le nombre de conteneurs pour une application donnée, était réduit.
Dans le cas d’une application multi-services nécessitant un nombre élevé de micro-services, de réseaux personnalisés ou de volumes persistants, l’approche de démarrage manuel de chacun des services peut devenir une tâche ardue et complexe.
Pour adresser ce type de problème, docker propose le module ‘docker-compose‘.
En utilisant le langage de représentation des données YAML, il est possible de représenter tous les services et paramètre d’un système donné et de démarrer le tout, en une seule ligne commande.
Voici un tableau présentant les analogies entre l’utilisation du cli de docker et de docker-compose :

Par les exemples suivants, nous verrons comment ca fonctionne.
Action 1.0 – Créer un système à partir de trois alpine
# Fichier: docker-compose.yml
# Auteur: Alain Boudreault
# Date: 2021.02.13
# Description: Mise en place d'un système de 3 alpine
version: "3.9"
services:
srv01:
image: alpine
container_name: serveur01 # Optionnel
srv02:
image: alpine
container_name: serveur02 # Optionnel
srv03:
image: alpine
container_name: serveur03 # Optionnel
Note: Voici le tableau de compatibilité des versions https://docs.docker.com/compose/compose-file/compose-file-v3/
Action 1.1 – Démarrer les services
docker-compose up Creating network "lab01-docker-compose_default" with the default driver Pulling srv01 (alpine:)... latest: Pulling from library/alpine 4c0d98bf9879: Pull complete Digest: sha256:08d6ca16c60fe7490c03d10dc339d9fd8ea67c6466dea8d558526b1330a85930 Status: Downloaded newer image for alpine:latest Creating serveur02 ... done Creating serveur01 ... done Creating serveur03 ... done Attaching to serveur02, serveur01, serveur03 serveur02 exited with code 0 serveur01 exited with code 0 serveur03 exited with code 0
Observons les lignes sélectionnées.
Équivalent docker run:
docker create network lab01-docker-compose_default docker run --name serveur01 --network lab01-docker-compose_default alpine docker run --name serveur02 --network lab01-docker-compose_default alpine docker run --name serveur03 --network lab01-docker-compose_default alpine
Action 1.2 – docker container ls (-a)
Action 1.3 – Réinitialiser docker:
docker container stop $(docker container ls -aq) docker system prune -af --volumes
Action 1.4 – Relancer les services en arrière plan, l’option -d
docker-compose up -d
NOTE: Les conteneurs seront arrêtés quand même.
Action 1.5 – attach et ping entre les services
docker attach serveur01 ping serveur02 CTRL+PQ
Action 2.0 – Ajout d’options supplémentaires – partie 01
Action 2.1 – Réinitialiser docker
Action 2.2 – Modifier le fichier docker-compose.yml pour y ajouter des options
version: "3.9"
services:
srv01:
image: alpine
container_name: serveur01
stdin_open: true # docker run -i
tty: true # docker run -t
networks:
- reseauAlpine
environment:
- JESUIS=Le spécialiste de la paresse
# command: sh
srv02:
image: alpine
container_name: serveur02
stdin_open: true # docker run -i
tty: true # docker run -t
networks:
- reseauAlpine
environment:
- JESUIS=Celui qui fait du sur place
# command: top
networks:
reseauAlpine:
name: jeSuisLeReseauAlpine
driver: bridge
Note: Pour les variables d’environnement, il est possible d’utiliser une des trois syntaxes suivantes:
Exemple 1: environment: MYSQL_ROOT_PASSWORD: donttell. # des paires clef:valeur MYSQL_USER: Bob _______________________________ Exemple 2: environment: - MYSQL_ROOT_PASSWORD=donttell # un tableau de chaines sans "" _______________________________ Exemple 3: environment: - "MYSQL_ROOT_PASSWORD=donttell" # un tableau de chaines avec ""
Action 2.3 – Relancer les services en arrière plan, l’option -d
Action 2.4 – Explorer le résultat
Action 2.5 – Ajout d’options supplémentaires – partie 02
Action 2.5.1 – Alpine avec un volume, fichier ‘docker-comp01.yml‘
# Fichier: docker-comp01.yml
version: "3.9"
services:
srv99:
image: alpine
container_name: serveur99
stdin_open: true # docker run -i
tty: true # docker run -t
volumes:
- ./:/420
Action 2.5.2 – Démarrer le système
docker-compose -f docker-comp01.yml up -d
Action 2.5.3 – Connexion au service alpine
docker exec -it serveur99 /bin/sh / ls / ls /420 / touch /420/note.txt
Action 2.6 – Configuration d’un service nginx
version: "3.9"
services:
serveurweb:
image: nginx
container_name: serveurWEB
volumes:
- ./templates/site.template:/etc/nginx/templates
- ./contenuweb:/usr/share/nginx/html:rw
ports:
- "8080:80"
environment:
- NGINX_HOST=monServeurWeb.com
- NGINX_PORT=80 # N'est pas utilisée dans cet exemple
Référence nginx
Action 3.1 – Renseigner le fichier docker-compose.yml suivant:
version: "3.9"
services:
maBD:
image: mariadb
environment:
- "MYSQL_ROOT_PASSWORD=root"
gestionBDviaAppWeb:
image: adminer
ports:
- "8080:8080"
depends_on:
- maBD
version: "3.9"
services:
srv01:
image: alpine
hostname: serveur01
container_name: serveur01
stdin_open: true # docker run -i
tty: true # docker run -t
networks:
- reseauAlpine
environment:
- JESUIS=Le spécialiste de la paresse
# command: sh
srv02:
image: alpine
container_name: serveur02
stdin_open: true # docker run -i
tty: true # docker run -t
networks:
- reseauAlpine
environment:
- JESUIS=Celui qui fait du sur place
command: top
srv99:
image: alpine
container_name: serveur99
stdin_open: true # docker run -i
tty: true # docker run -t
volumes:
- ./:/420
serveurweb:
image: nginx
container_name: serveurWEB
volumes:
- ./templates/site.template:/etc/nginx/templates
- ./contenuweb:/usr/share/nginx/html:rw
ports:
- "8080:80"
environment:
- NGINX_HOST=monServeurWeb.com
- NGINX_PORT=80 # N'est pas utilisée dans cet exemple
maBD:
image: mariadb
networks:
- reseauAdminer
environment:
- "MYSQL_ROOT_PASSWORD=root"
gestionBDviaAppWeb:
image: adminer
networks:
- reseauAdminer
ports:
- "8081:8080"
depends_on:
- maBD
networks:
reseauAlpine:
name: jeSuisLeReseauAlpine
driver: bridge
reseauAdminer:
name: jeSuisLeReseauAdminer
driver: bridge
1 – Démarrer, à partir d’un fichier docker-compose, le système de micro-services suivants:
2 – Créer, à partir de phpmyadmin, la base de données ‘wordpress‘.
3 – Vérifier que la BD a été créée sur votre disque local.
Note: Si le fichier n’est pas nommé docker-compose.yml alors il faut le nommer dans les commandes.
Par exemple,
docker-compose -f docker-labo02.yml up -d docker-compose -f docker-labo02.yml ps docker-compose -f docker-labo02.yml top docker-compose -f docker-labo02.yml logs # Note: Il faut utiliser le nom du service et non pas celui du conteneur. docker-compose -f docker-labo02.yml exec cie_db bash
Mettre en place un site wordpress, en utilisant docker-compose, pour la CIE_ABC, en respectant le devis suivant:
Action – Valider le fichier: docker-compose config
Action – docker-compose up
Action – docker-compose up -d
docker-compose logs
docker-compose ps
docker-compose stop
Docker-compose permet la mise en place d’images personnalisées pendant le processus de démarrage d’une application multi-services.
Première étape, renseigner les directives de construction de l’image.
Action 7.1 – Enregistrer, dans un dossier vide, le fichier Dockerfile:
# ###########################################################################
# Fichier: Dockerfile
# Auteur: Alain Boudreault
# Date: 2021.03.05
# Description: Exemple d'un Dockerfile avec,
#
# 1 - Des variables d'environnement,
# 2 - Un invite de commande personnalisé pour tous les 'users',
# 3 - Le démarrage automatique d'une application du conteneur.
# ###########################################################################
FROM debian
LABEL authors="Alain Boudreault <aboudrea@cstj.qc.ca>"
LABEL Atelier="7.1 de http://ve2cuy.com/420-4d4b/index.php/docker-compose-introduction-2/"
ENV UN_MOT_DE_PASSE=tepasserieux
ENV UNE_BASE_DE_DONNEES=db_de_la_ciex
# Definir des variables avec des séquences ANSI pour afficher de la couleur sous BASH
ENV RESET="\[\033[0m" \
ROUGE="\[\033[0;31m" \
VERT="\[\033[01;32m" \
BLEU="\[\033[01;34m" \
JAUNE="\[\033[0;33m"
# Sympathique petit (prompt) invite en couleur pour tous les utilisateurs
RUN echo 'export PS1="${VERT}\D{%H:%M:%S} - ${JAUNE}\u@docker${ROUGE}\nDossier: [\W]\n${RESET}\$ "' \
>> /etc/bash.bashrc
RUN apt-get update
RUN apt-get install git lynx -y
# Lancer le fureteur au démarrage. Tester avec http://lite.cnn.com/en
# CMD ["lynx", "http://lite.cnn.com/en"]
Action 7.1b – Bâtir l’image, pour un test intermédiaire.
Note: Avec docker-compose, il n’est pas nécessaire de bâtir l’image au préalable.
docker build -t perso .
Action 7.2 – Afficher les informations de l’image
docker inspect perso
Note: Remarquer les propriétés Author, Env et Labels
"Author": "Alain Boudreault <aboudrea@cstj.qc.ca>",
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"UN_MOT_DE_PASSE=tepasserieux",
"UNE_BASE_DE_DONNEES=db_de_la_ciex",
"RESET=\\[\\033[0m",
"ROUGE=\\[\\033[0;31m",
"VERT=\\[\\033[01;32m",
"BLEU=\\[\\033[01;34m",
"JAUNE=\\[\\033[0;33m"
],
"Labels": {
"Atelier": "7.1 de http://ve2cuy.com/420-4d4b/index.php/docker-compose-introduction-2/"
}
Action 7.3 – Renseigner le fichier docker-compose suivant:
version: '3.3'
# docker-compose build
# docker-compose up --build -d
# OU
# docker-compose up -d
services:
# Note: pas de caractères majuscules dans le nom du service
mondebian:
image: alainboudreault/serveur01
container_name: serveur01
build: .
restart: always
stdin_open: true # docker run -i
tty: true # docker run -t
environment:
- VERSION=action7.1
networks:
- reseau7.1
web:
image: nginx:latest
ports:
- "8000:80"
restart: always
volumes:
- ./web:/usr/share/nginx/html/perso
networks:
- reseau7.1
networks:
reseau7.1:
name: jeSuisLeReseau7.1
driver: bridge
Action 7.4 – Tester l’image perso
docker-compose exec mondebian bash # Note: pas de -it avec exec car le service roule déjà en mode -it ## Attention, il faut utiliser le nom du service dans les commandes $ env
Action 7.5 – Arrêter les services et effacer les images et les conteneurs
docker-compose down --rmi all
Dans un dossier vide ‘labo-08’
Renseigner un fichier docker-compose qui:
Défi supplémentaire pour le service Ubuntu (facultatif):
Le nom de la branche ‘master‘ devrait apparaitre dans l’invite.
Action 9.1 – Le fichier .env
DB_PORT=3306 DB_ROOT_PASS=password DB_USER=bob DB_PASS=password
Action 9.2 –
services:
db:
image: mariadb:10.4.13
ports:
- ${DB_PORT}:3306
volumes:
- ./db_data:/var/lib/mysql
tmpfs:
- /tmp/mysql-tmp
restart: always
environment:
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASS}"
MYSQL_USER: "${DB_USER}"
MYSQL_PASSWORD: "${DB_PASS}"
Note: voir la directive depends_on
fichier config.site
server {
listen ${PORT};
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
fichier docker-compose.yml
web: image: nginx volumes: - ./site.template:/etc/nginx/conf.d/site.template ports: - "3000:8080" environment: - PORT=8080 command: /bin/sh -c "envsubst < /etc/nginx/conf.d/site.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"