
Table des matières
- GlusterFS : stockage partagé
- Cluster MariaDB Galera
- Stack WordPress (Swarm via Dokploy)
- Exposition publique (Cloudflare Tunnel)
- Vérifications et test de bascule
Architecture & Nœuds

| Hostname | Rôle Swarm | Rôle DB |
|---|---|---|
| node-manager | Manager | |
| node-worker-1 | Worker | Galera node 1 |
| node-worker-2 | Worker | Galera node 2 |
| node-worker-3 | Worker | Galera node 3 |
1. GlusterFS : stockage partagé
Pourquoi GlusterFS ?
Sans stockage partagé, chaque réplica WordPress a ses propres fichiers. Un upload d’image sur le réplica 1 ne serait pas visible depuis le réplica 2. GlusterFS crée un volume distribué monté sur tous les nœuds, tous les réplicas voient exactement les mêmes fichiers en temps réel.
Installation sur les 3 workers
apt install glusterfs-server -y
systemctl enable --now glusterd
Création du cluster
Depuis worker-1 uniquement, déclarer les pairs :
gluster peer probe IP_WORKER2
gluster peer probe IP_WORKER3
gluster peer status
Création du volume répliqué
# Créer le dossier brique sur chaque worker
mkdir -p /gluster/wordpress
# Créer le volume depuis worker-1
gluster volume create wordpress replica 3 \
IP_WORKER1:/gluster/wordpress \
IP_WORKER2:/gluster/wordpress \
IP_WORKER3:/gluster/wordpress \
force
gluster volume start wordpress
gluster volume status wordpress
replica 3 signifie que chaque fichier est répliqué sur les 3 briques simultanément. Si un nœud tombe, GlusterFS bascule automatiquement vers les autres.
Montage sur chaque worker
mkdir -p /mnt/gluster/wordpress
mount -t glusterfs IP_LOCALE:/wordpress /mnt/gluster/wordpress
Ajouter dans /etc/fstab pour le montage automatique au démarrage :
IP_WORKER:/wordpress /mnt/gluster/wordpress glusterfs defaults,_netdev 0 0
2. Cluster MariaDB Galera
Principe
- 3 instances MariaDB synchronisées en temps réel
- Chaque conteneur WordPress se connecte à la DB locale via
172.17.0.1(bridge Docker de l’hôte) - Si un nœud tombe, les 2 autres continuent de fonctionner
Installation sur les 3 workers
apt install -y mariadb-server mariadb-client galera-4
Configuration Galera
Créer /etc/mysql/mariadb.conf.d/galera.cnf sur chaque worker, adapter wsrep_node_name et wsrep_node_address par nœud :
[mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0
# Galera Provider
wsrep_on=ON
wsrep_provider=/usr/lib/libgalera_smm.so
wsrep_cluster_name="galera-cluster"
wsrep_cluster_address="gcomm://IP_WORKER1,IP_WORKER2,IP_WORKER3"
# Adapter par nœud
wsrep_node_name="worker-1" # worker-2 / worker-3
wsrep_node_address="IP_WORKER1" # IP_WORKER2 / IP_WORKER3
wsrep_sst_method=rsync
Bootstrap du cluster
# Sur worker-1 UNIQUEMENT
systemctl stop mariadb
galera_new_cluster
# Sur les autres workers
systemctl start mariadb
Vérification
mysql -u root -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
Création de la base WordPress
Sur worker-1 uniquement, réplication automatique vers les autres :
CREATE DATABASE wpdb;
GRANT ALL PRIVILEGES ON wpdb.* TO 'wpdb_usr'@'%' IDENTIFIED BY '<MOT_DE_PASSE>';
FLUSH PRIVILEGES;
3. Stack WordPress (Swarm via Dokploy)
Services déployés
| Service | Image | Replicas | Placement |
|---|---|---|---|
| wordpress | wordpress:latest | 3 | node.role == worker |
| cloudflared | cloudflare/cloudflared:latest | 3 |
Variables d’environnement WordPress
WORDPRESS_DB_HOST=172.17.0.1
WORDPRESS_DB_USER=wpdb_usr
WORDPRESS_DB_PASSWORD=<MOT_DE_PASSE>
WORDPRESS_DB_NAME=wpdb
172.17.0.1 est le bridge Docker local, chaque réplica se connecte à l’instance MariaDB Galera de son propre hôte, sans trafic inter-nœuds pour les requêtes DB.
Volume partagé
/mnt/gluster/wordpress:/var/www/html
Labels Traefik
deploy:
replicas: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.wordpress.rule=Host(`monsite.com`)"
- "traefik.http.routers.wordpress.entrypoints=web"
- "traefik.http.services.wordpress.loadbalancer.server.port=80"
- "traefik.docker.lbswarm=true"
- "traefik.http.middlewares.wp-close.headers.customresponseheaders.Connection=close"
- "traefik.http.routers.wordpress.middlewares=wp-close"
placement:
constraints:
- node.role == worker
4. Exposition publique (Cloudflare Tunnel)
Architecture
Internet → Cloudflare → cloudflared (3 réplicas) → Traefik → WordPress
Chaque réplica cloudflared utilise le même token, Cloudflare enregistre chaque instance comme un connecteur distinct et bascule automatiquement si l’un tombe. Aucun port entrant à ouvrir sur les serveurs.
Configuration du service
- Image :
cloudflare/cloudflared:latest - Arguments :
tunnel --no-autoupdate run - Variable d’env :
TUNNEL_TOKEN=<TOKEN> - Replicas : 3
Route Cloudflare Zero Trust
Dans Zero Trust → Networks → Tunnels → Public Hostnames :
| Domaine | Service |
|---|---|
monsite.com | http://nom-service-wordpress:80 |
5. Vérifications et test de bascule
Vérifier la réplication GlusterFS
Uploader une image depuis WordPress (Médias → Ajouter) puis vérifier sur les 3 workers :
ls /mnt/gluster/wordpress/wp-content/uploads/
Test de bascule Swarm
# Simuler la panne d'un worker
docker node update --availability drain node-worker-1
# Vérifier la redistribution des réplicas
docker service ps nom-service-wordpress | grep Running
# Remettre le nœud en service
docker node update --availability active node-worker-1
Commandes GlusterFS utiles
gluster volume status wordpress # état du volume
gluster volume info wordpress # info détaillée
gluster peer status # état des pairs
gluster volume heal wordpress info # vérifier la synchronisation
Récapitulatif HA
| Composant | Redondance |
|---|---|
| Application WordPress | 3 réplicas Swarm |
| Stockage fichiers | GlusterFS répliqué sur 3 nœuds |
| Base de données | MariaDB Galera multi-master (3 nœuds) |
| Tunnel Cloudflare | 3 connecteurs cloudflared |
