Ce que j’ai fait
1. C’est quoi Docker Compose ?
Dans l’étape précédente, j’ai installé Docker. Mais mon site a besoin de 3 logiciels qui travaillent ensemble :
- MariaDB → la base de données (stocke les articles, les pages, etc.)
- WordPress → le moteur du site (génère les pages)
- Nginx → le serveur web (distribue les pages aux visiteurs)
Lancer ces 3 logiciels un par un avec des commandes à rallonge, ce serait galère. Docker Compose permet de tout décrire dans un seul fichier et de tout démarrer en une commande.
2. Qui parle avec qui ?
Avant de coder, j’ai réfléchi à comment ces 3 services doivent communiquer. L’idée c’est que la base de données ne soit jamais accessible depuis Internet.
Internet (les visiteurs)
│
▼
┌────────────┐
│ Nginx │ ← Le seul visible de l'extérieur
└─────┬──────┘
│
┌─────┴──────┐
│ WordPress │ ← Fabrique les pages
└─────┬──────┘
│
┌─────┴──────┐
│ MariaDB │ ← Invisible depuis Internet
└────────────┘Pour ça, j’ai créé deux réseaux internes dans Docker :
- frontend → relie Nginx et WordPress
- backend → relie WordPress et MariaDB
Résultat : Nginx ne peut pas toucher à la base de données, et personne sur Internet ne le peut non plus.
3. Les mots de passe (fichier .env)
Les mots de passe ne doivent jamais apparaître dans le code, ni sur GitHub. La solution : les mettre dans un fichier .env séparé, qui reste uniquement sur le serveur.
cd ~
mkdir -p portfolio && cd portfolio
nano .envDans ce fichier, j’ai mis toutes les infos sensibles sous cette forme :
MYSQL_ROOT_PASSWORD=mot_de_passe_genere_par_keepass
MYSQL_DATABASE=nom_de_la_base
MYSQL_USER=nom_utilisateur_base
MYSQL_PASSWORD=autre_mot_de_passe_genere
WORDPRESS_DB_HOST=db:3306
WORDPRESS_DB_NAME=nom_de_la_base
WORDPRESS_DB_USER=nom_utilisateur_base
WORDPRESS_DB_PASSWORD=autre_mot_de_passe_genereEnsuite j’ai verrouillé le fichier pour que seul mon utilisateur puisse le lire :
chmod 600 .env4. Le fichier docker-compose.yml
C’est le fichier qui décrit toute mon infrastructure :
nano docker-compose.ymlservices:
db:
image: mariadb:10.11
container_name: portfolio-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- db_data:/var/lib/mysql
networks:
- backend
wordpress:
image: wordpress:6.7-php8.3-fpm
container_name: portfolio-wp
restart: unless-stopped
depends_on:
- db
environment:
WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST}
WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
volumes:
- wp_data:/var/www/html
networks:
- frontend
- backend
webserver:
image: nginx:1.27
container_name: portfolio-nginx
restart: unless-stopped
depends_on:
- wordpress
ports:
- "80:80"
- "443:443"
volumes:
- wp_data:/var/www/html:ro
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- frontend
volumes:
db_data:
wp_data:
networks:
frontend:
backend:Ce qu’il faut retenir :
- Les ${…} vont chercher les valeurs dans le fichier .env automatiquement
- mariadb:10.11 et pas mariadb:latest → je fixe la version pour éviter les mauvaises surprises
- Pas de ports: sur db → la base de données n’est pas accessible de l’extérieur
- :ro sur les volumes Nginx = lecture seule (il peut lire les fichiers mais pas les modifier)
- restart: unless-stopped = les conteneurs redémarrent tout seuls si le serveur reboot
5. La configuration de Nginx
Nginx a besoin de savoir comment transmettre les demandes des visiteurs à WordPress.
mkdir -p ~/portfolio/nginx
nano ~/portfolio/nginx/default.confserver {
listen 80;
server_name _;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
location ~ /\.ht {
deny all;
}
}En gros :
- Si un visiteur demande une page → Nginx la transmet à WordPress
- Si c’est une image ou un fichier CSS → Nginx l’envoie directement (plus rapide)
- Les fichiers cachés (.htaccess etc.) sont bloqués
6. Lancement
cd ~/portfolio
# Tout démarrer
docker compose up -d
# Vérifier que les 3 conteneurs tournent
docker compose ps
# Lire les logs pour voir si tout va bien
docker compose logsSi les 3 conteneurs affichent « running », c’est gagné. 🎉
7. Commandes utiles pour la suite
# Tout arrêter
docker compose down
# Voir les logs d'un seul service
docker compose logs db
# Redémarrer après un changement
docker compose down && docker compose up -d