
Exemples pratiques (WordPress + DB, application web + API + DB)
Apprenez à utiliser Docker Compose à travers des exemples concrets : déploiement d'un site WordPress avec base de données et d'une application web multi-tiers.
Mettre la théorie en pratique : illustrer la puissance de Compose
Après avoir exploré la syntaxe du fichier `docker-compose.yml` et les commandes essentielles, la meilleure façon de consolider votre compréhension est de voir Docker Compose en action sur des scénarios réels. Ces exemples pratiques illustrent comment Compose simplifie radicalement le déploiement et la gestion d'applications composées de plusieurs services interconnectés.
Nous allons détailler deux cas d'usage très courants : le déploiement d'un site WordPress complet avec sa base de données MariaDB, et la mise en place d'une architecture web plus générique à trois niveaux (Frontend + Backend API + Base de données PostgreSQL). Pour chaque exemple, nous fournirons un fichier `docker-compose.yml` fonctionnel et expliquerons les choix effectués.
Ces exemples servent de point de départ que vous pourrez adapter à vos propres projets. Ils mettent en évidence l'utilisation des services, des volumes nommés pour la persistance, des réseaux implicites ou explicites, des variables d'environnement pour la configuration et des dépendances de démarrage.
Exemple 1 : Déployer WordPress avec une base de données MariaDB
WordPress est l'un des systèmes de gestion de contenu (CMS) les plus populaires au monde. Il nécessite une base de données (typiquement MySQL ou MariaDB) pour fonctionner. Docker Compose rend son déploiement trivial.
Créez un fichier nommé `docker-compose.yml` avec le contenu suivant :
version: '3.8' # Bien que facultatif, peut aider certains outils
services:
db:
# Utilise l'image officielle MariaDB
image: mariadb:10.6
container_name: wordpress_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: changeme_root_password # A CHANGER ABSOLUMENT
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: changeme_user_password # A CHANGER ABSOLUMENT
volumes:
# Volume nommé pour la persistance des données de la DB
- db_data:/var/lib/mysql
networks:
- wordpress-net
wordpress:
# Utilise l'image officielle WordPress
image: wordpress:latest
container_name: wordpress_app
restart: always
ports:
# Expose le port 80 du conteneur sur le port 8080 de l'hôte
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306 # 'db' est le nom du service de la base de données
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: changeme_user_password # Doit correspondre à celui de la DB
WORDPRESS_DB_NAME: wordpress
volumes:
# Volume optionnel pour persister le contenu de /var/www/html (thèmes, plugins, uploads)
# Alternative : bind mount si vous développez un thème/plugin: './wp-content:/var/www/html/wp-content'
- wp_content:/var/www/html
depends_on:
# S'assure que le conteneur 'db' est démarré avant 'wordpress'
- db
networks:
- wordpress-net
# Déclaration des volumes nommés
volumes:
db_data:
wp_content:
# Déclaration du réseau personnalisé (bonne pratique)
networks:
wordpress-net:
driver: bridgeExplication :- Services : Nous définissons deux services : `db` pour la base de données MariaDB et `wordpress` pour l'application WordPress elle-même.
- Images : Nous utilisons les images officielles `mariadb:10.6` et `wordpress:latest`.
- Environnement (`environment`) : Des variables d'environnement sont cruciales pour configurer la base de données (utilisateur, mot de passe, nom de la base) et pour dire à WordPress comment s'y connecter. Notez que `WORDPRESS_DB_HOST` est défini à `db:3306`, utilisant le nom du service `db` que Compose résoudra en l'adresse IP correcte sur le réseau interne `wordpress-net`. N'oubliez pas de changer les mots de passe par défaut !
- Volumes (`volumes`) : Nous déclarons deux volumes nommés : `db_data` (essentiel pour que les données de la base de données survivent aux redémarrages) et `wp_content` (pour persister les thèmes, plugins et uploads de WordPress). Ils sont définis au niveau supérieur puis montés dans les conteneurs respectifs.
- Réseau (`networks`) : Nous créons un réseau `bridge` personnalisé `wordpress-net` et connectons les deux services à ce réseau.
- Dépendance (`depends_on`) : `wordpress` dépend de `db`, garantissant que Compose démarre le conteneur `db` avant le conteneur `wordpress`.
- Ports (`ports`) : Nous mappons le port 80 (HTTP standard) du conteneur WordPress au port 8080 de notre machine hôte.
- Enregistrez le contenu ci-dessus dans un fichier `docker-compose.yml`.
- Ouvrez un terminal dans le même répertoire.
- Exécutez :
docker compose up -d - Attendez quelques instants que les conteneurs démarrent et que WordPress s'initialise.
- Ouvrez votre navigateur et allez à `http://localhost:8080`. Vous devriez voir l'écran d'installation de WordPress.
- Pour arrêter et supprimer les conteneurs et le réseau :
docker compose down - Pour arrêter, supprimer les conteneurs/réseau ET les volumes (données perdues !) :
docker compose down -v
Exemple 2 : Application Web (React) + API (Node.js) + DB (PostgreSQL)
Ce scénario représente une architecture microservice ou trois-tiers courante, idéale pour le développement local.
Supposons que vous ayez le code source de votre frontend React dans un dossier `./frontend` et celui de votre API Node.js dans `./backend`.
Créez un fichier `docker-compose.yml` :
version: '3.8'
services:
# Service Base de données PostgreSQL
db:
image: postgres:14-alpine
container_name: myapp_db
restart: unless-stopped
environment:
POSTGRES_DB: myapp_db
POSTGRES_USER: myapp_user
POSTGRES_PASSWORD: myapp_password # A CHANGER
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- backend-net
# Service Backend API (Node.js)
backend:
# Construit l'image à partir du Dockerfile dans le dossier ./backend
build:
context: ./backend
dockerfile: Dockerfile # Assurez-vous d'avoir un Dockerfile ici
container_name: myapp_backend
restart: unless-stopped
depends_on:
- db
environment:
DATABASE_URL: postgresql://myapp_user:myapp_password@db:5432/myapp_db # Connexion à la DB
NODE_ENV: development
PORT: 5000
volumes:
# Bind mount pour le code source (hot-reloading pendant le dev)
- ./backend:/usr/src/app
# Volume pour éviter d'écraser node_modules si présent dans l'image
- /usr/src/app/node_modules
ports:
# Expose le port 5000 du conteneur sur le port 5000 de l'hôte
- "5000:5000"
networks:
- backend-net
- frontend-net
# Service Frontend (React)
frontend:
# Construit l'image à partir du Dockerfile dans le dossier ./frontend
build:
context: ./frontend
dockerfile: Dockerfile # Assurez-vous d'avoir un Dockerfile ici (souvent avec un serveur Node)
container_name: myapp_frontend
restart: unless-stopped
depends_on:
- backend # Dépendance logique, l'API doit être là
environment:
# L'URL de l'API doit pointer vers le service backend
# Note: la communication se fait depuis le navigateur de l'utilisateur vers l'hôte,
# donc on utilise localhost:5000 (port exposé de l'API sur l'hôte)
# ou mieux, configurer un proxy dans le serveur de dev frontend
REACT_APP_API_URL: http://localhost:5000 # Ou configurer le proxy
volumes:
# Bind mount pour le code source (hot-reloading pendant le dev)
- ./frontend:/app
# Volume pour node_modules
- /app/node_modules
ports:
# Expose le port 3000 (port de dev React typique) sur le port 3000 de l'hôte
- "3000:3000"
networks:
- frontend-net
# Définition des volumes nommés
volumes:
postgres_data:
# Définition des réseaux
networks:
frontend-net:
driver: bridge
backend-net:
driver: bridgeExplication :- Services : Trois services : `db` (PostgreSQL), `backend` (Node.js API), `frontend` (React App).
- Build (`build`) : Pour `frontend` et `backend`, nous utilisons `build:` pour construire les images localement à partir des Dockerfiles dans les dossiers respectifs. C'est typique en développement pour refléter les changements de code.
- Volumes (`volumes`) : Un volume nommé `postgres_data` pour la base de données. Des bind mounts (`./backend:/usr/src/app`, `./frontend:/app`) sont utilisés pour monter le code source local dans les conteneurs, permettant le hot-reloading si configuré dans vos serveurs de développement Node/React. On utilise aussi un volume anonyme pour `node_modules` afin d'éviter que le bind mount n'écrase le dossier `node_modules` potentiellement installé lors du build de l'image.
- Réseaux (`networks`) : Deux réseaux distincts sont créés : `frontend-net` et `backend-net`. Le frontend est uniquement sur `frontend-net`, la DB uniquement sur `backend-net`. L'API (`backend`) est connectée aux deux, agissant comme un pont contrôlé. Cela améliore la sécurité en empêchant le frontend d'accéder directement à la DB.
- Environnement (`environment`) : La variable `DATABASE_URL` dans le `backend` utilise le nom de service `db` pour la connexion. La variable `REACT_APP_API_URL` dans le `frontend` est un peu plus subtile : comme le code React s'exécute dans le navigateur de l'utilisateur (hors du réseau Docker interne), il doit cibler l'API via le port exposé sur l'hôte (`localhost:5000`) ou via un proxy configuré dans le serveur de développement React.
- Ports (`ports`) : Le port 3000 est exposé pour le frontend et le port 5000 pour le backend.
- Assurez-vous d'avoir des Dockerfiles fonctionnels dans `./frontend` et `./backend`.
- Placez ce `docker-compose.yml` à la racine de votre projet.
- Exécutez :
(Le `--build` est utile la première fois ou après des changements majeurs).docker compose up -d --build - Accédez à votre frontend sur `http://localhost:3000`.
- L'API devrait être accessible sur `http://localhost:5000`.
- Utilisez `docker compose down -v` pour nettoyer complètement.
Conclusion des exemples
Ces deux exemples illustrent la flexibilité et la puissance de Docker Compose pour définir et gérer des applications multi-conteneurs. Que ce soit pour déployer rapidement des applications standards comme WordPress ou pour configurer un environnement de développement complexe pour votre propre application, Compose offre une solution déclarative, reproductible et facile à utiliser.
N'hésitez pas à adapter ces exemples, à explorer d'autres options du fichier `docker-compose.yml` (comme les `healthchecks`, `secrets`, `configs`) et à intégrer Compose dans vos workflows de développement et de test.