Docker Compose — Application multi-conteneurs

Fiche mission

Technicien : Dufosse
Module : BTS SIO SISR — VIRT-05 « Introduction à Docker Compose »
Environnement : VM Ubuntu 26.04, Docker Compose v2

Contexte et objectifs

Docker Compose permet de décrire et de lancer une application composée de plusieurs conteneurs à partir d'un seul fichier YAML. Chaque conteneur devient un service, et le fichier définit aussi les réseaux et les volumes. C'est une forme simple d'Infrastructure as Code : toute l'architecture se déploie avec une seule commande, docker compose up -d.

J'ai construit progressivement une stack de trois services : un serveur web nginx, un serveur de base de données MariaDB et un client MariaDB construit à partir de mon propre Dockerfile. J'ai ensuite rendu la base persistante avec un volume, puis isolé la base sur un réseau interne en supprimant son exposition sur l'hôte.

Docker Compose YAML Infrastructure as Code MariaDB nginx Alpine Linux

Étape A — Premiers services

Preuve 1 — Service web nginx

Premier service du Compose file : un serveur nginx basé sur l'image nginx:alpine, publié sur le port 8080 de la VM et relancé automatiquement en cas d'arrêt (restart: unless-stopped).

services:
  web:
    image: nginx:alpine
    container_name: my-web-server
    ports:
      - "8080:80"
    environment:
      - NGINX_HOST=localhost
      - NGINX_PORT=80
    restart: unless-stopped
Page d'accueil nginx sur le port 8080
docker compose up Publication de ports
Preuve 2 — Serveur de base de données

J'ai ajouté un service db_server basé sur l'image officielle MariaDB, avec le mot de passe root défini par variable d'environnement et la base exposée sur le port 33060 de l'hôte.

  db_server:
    image: mariadb:latest
    container_name: db_server
    ports:
      - "33060:3306"
    environment:
      - MARIADB_ROOT_PASSWORD=BTS_Ynov26
    restart: unless-stopped

Le mot de passe est volontairement laissé en clair : c'est celui d'un environnement de TP, supprimé à la fin de la séance. En production, il serait sorti du fichier Compose (fichier .env exclu de Git ou secret Docker).

Lancement de db_server avec docker compose

Les logs montrent deux fois « ready for connections » : au premier lancement, le script d'initialisation démarre un serveur temporaire pour créer la base et appliquer le mot de passe, puis lance le serveur définitif.

Logs MariaDB ready for connections
MariaDB Variables d'environnement docker compose logs

Étape B — Conteneur construit par Compose

Preuve 3 — Dockerfile du client

J'ai écrit un Dockerfile basé sur Alpine Linux qui installe uniquement le client MariaDB et Bash, puis garde le conteneur actif pendant une heure pour pouvoir s'y connecter.

FROM alpine:latest
RUN apk add --no-cache mariadb-client bash
CMD ["bash", "-c", "sleep 3600 & wait"]
Build de l'image client

Avant de l'intégrer au Compose file, je l'ai testé seul. Le conteneur contient bien bash et mariadb-client ; mariadb-common n'est qu'une dépendance du client, aucun serveur n'est installé.

Vérification des paquets installés
Dockerfile Alpine Linux apk
Preuve 4 — Service db_client

Le service db_client utilise build: . : Compose construit lui-même l'image à partir du Dockerfile du dossier. depends_on garantit que la base démarre avant le client.

  db_client:
    build: .
    container_name: db_client
    depends_on:
      - db_server
Les trois services lancés

Depuis le client, je me connecte à la base en utilisant simplement le nom du service db_server, résolu par le DNS interne de Docker.

Connexion au serveur MariaDB depuis le client
build depends_on DNS Docker

Étape C — Persistance de la base

Preuve 5 — Test sans volume puis avec volume

Pour prouver la persistance, j'ai créé une base test_persistance contenant une table et une ligne, puis supprimé et recréé les conteneurs avec docker compose down puis docker compose up -d.

Sans volume, la base a disparu : seules les bases système subsistent.

Base perdue sans volume

J'ai alors ajouté un volume nommé db_data, monté sur /var/lib/mysql où MariaDB stocke ses fichiers, et refait exactement le même test.

  db_server:
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Avec le volume, les données sont toujours présentes après recréation.

Données conservées avec le volume

docker compose down supprime les conteneurs mais conserve les volumes nommés (sauf avec l'option -v).

Volumes Persistance SQL

Étape D — Isolation réseau

Preuve 6 — Réseau interne backend

Exposer une base de données sur l'hôte n'est pas une bonne pratique de sécurité. J'ai donc créé un réseau backend réservé à db_server et db_client, et supprimé la publication du port 33060. Le service web reste seul sur le réseau par défaut.

name: myapp

services:
  web:
    image: nginx:alpine
    container_name: my-web-server
    ports:
      - "8080:80"
    environment:
      - NGINX_HOST=localhost
      - NGINX_PORT=80
    restart: unless-stopped

  db_server:
    image: mariadb:latest
    container_name: db_server
    environment:
      - MARIADB_ROOT_PASSWORD=BTS_Ynov26
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - backend
    restart: unless-stopped

  db_client:
    build: .
    container_name: db_client
    depends_on:
      - db_server
    networks:
      - backend

volumes:
  db_data:

networks:
  backend:
Création du réseau backend et recréation des services db_server sans port publié Réseaux myapp_backend et myapp_default
Networks Segmentation Sécurité
Preuve 7 — Validation
VérificationRésultat attenduRésultat
docker compose psdb_server n'a plus de port publiéOK
docker network lsRéseaux myapp_backend et myapp_defaultOK
ss -tlnp | grep 33060Aucun processus en écouteOK
Requête depuis db_clientDonnées toujours accessiblesOK
Port 33060 fermé sur l'hôte Accès à la base depuis le réseau interne

La base n'est plus joignable depuis la VM ni depuis le réseau local, mais le client y accède toujours via le réseau interne. Ce dernier test valide en même temps l'isolation réseau et la persistance, puisque les données ont survécu à la recréation de db_server.

ss Tests de validation Moindre exposition

Bilan

Compétences mobilisées

Ce TP m'a permis de passer de conteneurs lancés un par un à une architecture complète décrite dans un seul fichier versionnable : services, image construite sur mesure, volume persistant et segmentation réseau. C'est la même approche que j'utilise sur mon serveur personnel, où l'ensemble des services est déployé avec Docker Compose.

Docker Compose Infrastructure as Code Bases de données Sécurité réseau