Le besoin / Le problème serveur
Si vous avez déjà vu un site Multisite répondre en boucle en 301, servir le mauvais site sur le bon domaine, ou casser les médias (404 sur /wp-content/uploads/sites/), le problème vient rarement de WordPress lui‑même. Il vient presque toujours de la couche serveur : DNS, vhost, TLS, règles de réécriture, ou cache.
Un réseau WordPress (WordPress 6.9.4, avril 2026) vous permet d’héberger plusieurs sites avec un seul cœur WordPress, un seul ensemble de plugins/thèmes (avec activation réseau), et une base de données partagée. C’est très efficace… à condition de configurer le serveur comme un reverse-proxy et un routeur de sites, pas comme un simple “site unique”.
À la fin, vous saurez : choisir sous-domaines vs sous-répertoires, préparer un vhost robuste (Nginx ou Apache), activer Multisite via wp-config.php, appliquer les règles de rewrite correctes, gérer le réseau au quotidien avec WP‑CLI, et surtout migrer/restaurer sans casser la correspondance domaines ↔ sites.
Résumé rapide
- Sous-domaines : nécessite DNS wildcard et souvent un certificat wildcard ; plus flexible pour mapper des domaines.
- Sous-répertoires : plus simple côté DNS/TLS, mais attention aux collisions d’URL et aux règles de rewrite.
- Le serveur doit préserver
Hostet servir WordPress sur un seuldocument_rootavec des rewrites Multisite. - WP-CLI est votre “panneau de contrôle” : création de sites, mapping, recherche/remplacement, flush des caches.
- Migrations : export SQL + fichiers + mise à jour des tables
wp_blogs/wp_site+ search/replace ciblé, sinon vous cassez les URLs. - Cache : un cache mal “variant” par
Hostsert le site A sur le domaine B. C’est fréquent avec Nginx fastcgi_cache mal configuré.
Avant de commencer (prérequis)
Accès et outils
- SSH sur le serveur (ou au minimum un shell sur le conteneur).
- WP-CLI (recommandé). Référence : WP-CLI Commands.
- Accès à MySQL/MariaDB en ligne de commande (
mysql,mysqldump). - Accès aux fichiers (SFTP/rsync). Évitez FTP en 2026 si vous pouvez.
Versions serveur recommandées (2026)
- WordPress : 6.9.4 (vous l’avez déjà).
- PHP : 8.1+ (8.2/8.3 très courant). Référence : PHP Supported Versions.
- MySQL : 8.0+ ou MariaDB : 10.6+ (évitez les versions trop anciennes, surtout pour la perf et les collations).
- Nginx ou Apache (les deux fonctionnent, mais Nginx est souvent plus simple à “verrouiller” en cache).
Sauvegarde obligatoire (et test de restauration)
Ne testez pas Multisite sur production sans restauration validée. J’ai souvent vu des migrations où wp-config.php est modifié, puis impossible de revenir car la base a été partiellement “multisitée”.
# Chemin WordPress (adaptez)
cd /var/www/example.com/public
# 1) Sauvegarde fichiers (hors cache)
tar --exclude='./wp-content/cache' --exclude='./wp-content/uploads/cache'
-czf /root/backup-files-$(date +%F).tar.gz .
# 2) Sauvegarde base (adaptez DB_NAME/DB_USER)
# Astuce : récupérez les infos depuis wp-config.php
mysqldump --single-transaction --quick --routines --triggers
-u'wp_user' -p'wp_pass' wp_db > /root/backup-db-$(date +%F).sql
Étape 1 : Choisir le mode Multisite (sous-domaines vs sous-répertoires)
Sous-répertoires
Exemple : example.com/site1, example.com/site2. Côté serveur, c’est le plus simple : un seul domaine, pas de wildcard DNS, pas de certificat wildcard.
- Avantage : mise en place rapide, moins de variables réseau.
- Inconvénient : si votre site principal utilise déjà des slugs “réservés”, vous pouvez créer des collisions (ex : une page
/bloget un site/blog).
Sous-domaines
Exemple : site1.example.com, site2.example.com. C’est souvent le meilleur choix si vous prévoyez du domain mapping (ex : client-a.com pointe vers un site du réseau).
- Avantage : isolation par host, plus propre pour le cache et les proxys.
- Inconvénient : nécessite DNS wildcard (
*.example.com) et idéalement TLS wildcard.
Compatibilité Divi 5 / Elementor / Avada
Les trois fonctionnent en Multisite, mais la réalité terrain est la gestion des licences et des “bibliothèques globales”. Sur des réseaux clients, je recommande :
- Activer le page builder par site (pas en réseau) si vous voulez limiter l’impact d’un bug.
- Garder un site “staging interne” du réseau pour tester les mises à jour du builder et des modules.
Étape 2 : Préparer DNS, vhost et TLS (wildcard si besoin)
DNS (sous-domaines)
Vous devez créer un enregistrement wildcard. Exemple (conceptuel) :
A:example.com→ IP du serveurA:*.example.com→ IP du serveur
Sans wildcard, WordPress créera des sites, mais le DNS ne résoudra pas, et vous perdrez du temps à diagnostiquer “WordPress ne marche pas”.
TLS (Let’s Encrypt / wildcard)
Un wildcard Let’s Encrypt nécessite généralement un challenge DNS (selon votre stack). Si vous ne pouvez pas faire de wildcard, alternative réaliste : utiliser un certificat multi-domaines pour les sous-domaines connus, mais ça devient vite ingérable.
Vhost : un seul document_root
Le réseau Multisite doit pointer vers le même document_root WordPress. Ne créez pas un vhost par sous-site avec des racines différentes : vous allez casser les uploads, les cookies et la résolution des sites.
Étape 3 : Activer Multisite proprement (wp-config.php)
L’activation se fait en deux temps : (1) autoriser l’installation Multisite, (2) injecter les constantes du réseau. La doc officielle reste la référence : Multisite Installation.
1) Autoriser l’installation Multisite
Ajoutez ceci dans wp-config.php, idéalement juste au-dessus de la ligne “stop editing”.
<?php
// Autorise l'écran "Configuration du réseau" dans l'admin.
// À retirer éventuellement après installation si vous voulez verrouiller le setup.
define( 'WP_ALLOW_MULTISITE', true );
/* C'est tout, ne touchez pas à ce qui suit ! */
2) Installer via l’admin (sans captures)
Ensuite, côté WordPress (admin), vous générez les constantes Multisite. Je ne mets pas de capture, mais le résultat final est du code à coller dans wp-config.php et des règles de rewrite à appliquer.
Point concret : choisissez sous-domaines ou sous-répertoires dès maintenant. Changer après coup est faisable, mais c’est une migration (DNS, URLs, cookies), pas un simple toggle.
Constantes Multisite typiques (exemple)
Exemple pour un réseau en sous-domaines sur example.com. Adaptez domaine et chemins.
<?php
// --- Configuration Multisite (WordPress 6.9.4+) ---
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', true );
// Domaine et chemin "racine" du réseau.
define( 'DOMAIN_CURRENT_SITE', 'example.com' );
define( 'PATH_CURRENT_SITE', '/' );
// Site principal (blog_id) et réseau (site_id).
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );
// Optionnel : si vous êtes derrière un proxy/Load Balancer
// et que vous gérez HTTPS au niveau du proxy.
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
$_SERVER['HTTPS'] = 'on'; // Force WordPress à générer des URLs en https
}
Erreur réaliste : copier au mauvais endroit
Je vois souvent des constantes Multisite collées après la ligne “stop editing”. Dans ce cas, WordPress ne les lit pas, et vous vous retrouvez avec une admin qui “oublie” le réseau à chaque refresh. Gardez-les avant la fin du fichier.
Étape 4 : Règles de réécriture (Nginx/Apache) et pièges de cache
Voici ce qui se passe en coulisses : WordPress route les sous-sites via l’URL et/ou l’host, mais le serveur doit d’abord envoyer toutes les requêtes “non-fichiers” vers index.php. En Multisite, il y a en plus des règles spécifiques pour wp-admin et pour les uploads “sites”.
Nginx : points non négociables
- Le bloc
server_namedoit couvrir le domaine et (si sous-domaines) le wildcard. - Le
try_filesdoit rediriger vers/index.phpavec les args. - Les accès à
/wp-admindoivent gérer le slash final.
Apache : attention au .htaccess et à AllowOverride
Si AllowOverride est désactivé, votre .htaccess ne sert à rien. Résultat typique : l’admin marche, mais tous les sous-sites renvoient 404. Vérifiez la conf Apache, pas seulement le fichier.
Piège cache (fastcgi_cache / proxy_cache)
Le bug classique : le cache ne varie pas par $host. Du coup, site1.example.com met en cache la home, puis site2.example.com reçoit la home de site1. J’ai croisé ça sur des stacks “optimisées” à la main.
Si vous faites du cache Nginx, la clé doit inclure $scheme$host$request_uri au minimum.
Étape 5 : Gérer le réseau au quotidien avec WP-CLI
WP‑CLI est le moyen le plus fiable de gérer un réseau sans passer par des écrans qui masquent des détails. Doc : wp site et wp network.
Lister et auditer les sites
cd /var/www/example.com/public
# Liste des sites
wp site list --fields=blog_id,url,registered,last_updated,public,archived,deleted,spam
# Détails d'un site (blog_id = 3)
wp site get 3
Créer un site
# Sous-domaines : --slug crée site3.example.com
wp site create --slug=site3 --title="Site 3" [email protected]
# Sous-répertoires : --slug crée example.com/site3
wp site create --slug=site3 --title="Site 3" [email protected]
Activer/désactiver un plugin sur tout le réseau
# Activation réseau (mu-plugins mis à part)
wp plugin activate --network redis-cache
# Désactivation réseau
wp plugin deactivate --network redis-cache
Mettre à jour WordPress et les extensions (avec prudence)
Sur Multisite, une mise à jour de plugin “global” impacte tous les sites. Mon habitude : mise à jour en staging, puis en prod avec une fenêtre et un rollback prêt.
# Core
wp core update
wp core update-db
# Plugins et thèmes
wp plugin update --all
wp theme update --all
Recherche/remplacement (migration, HTTPS, mapping)
Le search-replace est l’outil qui sauve… et celui qui détruit si vous le lancez au mauvais périmètre. Faites un --dry-run d’abord.
# Exemple : passage http -> https sur tout le réseau
wp search-replace 'http://example.com' 'https://example.com' --all-tables --network --dry-run
# Puis exécution réelle
wp search-replace 'http://example.com' 'https://example.com' --all-tables --network
Erreur réaliste : oublier –network
Sans --network, vous pouvez ne modifier que le site courant (selon contexte), et vous vous retrouvez avec un réseau “mixte” où certains sites génèrent encore des URLs en HTTP. C’est pénible à déboguer parce que ça ressemble à un cache.
Étape 6 : Staging, migration et restauration d’un Multisite
Un Multisite se migre comme un site unique, sauf que vous avez des contraintes supplémentaires : tables multiples (wp_2_options, wp_3_posts, etc.), table de routage (wp_blogs), et parfois du domain mapping. Le serveur doit être prêt avant d’importer la base.
Créer un staging (copie) via SSH + MySQL + rsync
Approche simple et robuste : cloner fichiers + base, puis ajuster domaine et TLS.
# 1) Copier les fichiers (exemple vers /var/www/staging)
rsync -aHAX --delete
--exclude='wp-content/cache/'
/var/www/example.com/public/
/var/www/staging.example.com/public/
# 2) Dumper la base prod
mysqldump --single-transaction --quick
-u'wp_user' -p'wp_pass' wp_db > /root/prod.sql
# 3) Importer dans la base staging
mysql -u'stg_user' -p'stg_pass' stg_db < /root/prod.sql
Adapter le domaine du réseau (cas le plus fréquent)
Si votre staging est sur staging.example.com, votre réseau en sous-domaines devient souvent *.staging.example.com. Deux options :
- Option A : vous gardez
DOMAIN_CURRENT_SITEàexample.comet vous forcez des hosts via /etc/hosts (pratique en local, moins en serveur). - Option B : vous changez
DOMAIN_CURRENT_SITEet mettez à jour la base (plus réaliste en staging serveur).
Pour l’option B, vous devez mettre à jour au minimum la table wp_site et wp_blogs (préfixe variable). Exemple SQL (adaptez préfixe et domaines) :
mysql -u'stg_user' -p'stg_pass' stg_db
-- Remplacez wp_ par votre préfixe réel
UPDATE wp_site SET domain = 'staging.example.com' WHERE id = 1;
-- Sous-domaines : met à jour les domaines de chaque site
UPDATE wp_blogs
SET domain = REPLACE(domain, '.example.com', '.staging.example.com')
WHERE domain LIKE '%.example.com';
-- Site principal (souvent example.com sans sous-domaine)
UPDATE wp_blogs
SET domain = 'staging.example.com'
WHERE blog_id = 1;
Puis faites un search-replace pour les URLs stockées dans le contenu (en restant prudent).
wp search-replace 'https://example.com' 'https://staging.example.com' --all-tables --network --dry-run
wp search-replace 'https://example.com' 'https://staging.example.com' --all-tables --network
Restauration (retour arrière) : stratégie réaliste
- Restaurez fichiers + base ensemble (évitez de mélanger un dump J-1 avec des uploads J).
- Si vous utilisez Redis/Object Cache, videz-le après restauration (sinon vous servez des options obsolètes).
# Exemple : purge Redis si vous utilisez un cache objet Redis
redis-cli FLUSHDB
Fichiers de configuration complets
Les exemples ci-dessous sont prêts à copier-coller, mais adaptez chemins, sockets PHP-FPM, domaines et politiques TLS. Je fournis Nginx et Apache, parce que les deux existent encore largement en 2026.
Nginx : server block Multisite (sous-domaines)
# /etc/nginx/sites-available/example.com.conf
server {
listen 80;
listen [::]:80;
server_name example.com *.example.com;
# Redirection vers HTTPS (adaptez si vous terminez TLS ailleurs)
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com *.example.com;
root /var/www/example.com/public;
index index.php;
# --- TLS (exemple) ---
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Taille upload (Multisite = médias, donc on évite 2M par défaut)
client_max_body_size 128m;
# Sécurité basique (voir section sécurité pour plus)
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
# Logs
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log warn;
# --- WordPress Multisite rewrites ---
location / {
try_files $uri $uri/ /index.php?$args;
}
# Évite les redirections bizarres sur /wp-admin
location = /wp-admin {
return 301 /wp-admin/;
}
# PHP
location ~ .php$ {
include snippets/fastcgi-php.conf;
# Adaptez : socket php-fpm ou host:port
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
# Important : évite certaines attaques PATH_INFO
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# Bloque l'exécution PHP dans uploads (fréquent vecteur d'infection)
location ~* ^/wp-content/uploads/.*.php$ {
deny all;
}
# Cache statique long (attention : plugins de cache peuvent gérer autrement)
location ~* .(css|js|jpg|jpeg|png|gif|webp|svg|ico|woff2?)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000, immutable";
try_files $uri =404;
}
}
Apache : .htaccess Multisite (sous-répertoires)
Ce fichier suppose que mod_rewrite est actif et que AllowOverride All est permis sur le vhost.
# /var/www/example.com/public/.htaccess
# --- WordPress Multisite (sous-répertoires) ---
RewriteEngine On
RewriteBase /
# Protège wp-config.php (utile si mal configuré ailleurs)
<Files wp-config.php>
Require all denied
</Files>
# Évite index.php dans l'URL
RewriteRule ^index.php$ - [L]
# Ajoute le slash final à /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
# Si le fichier/dossier existe, on sert directement
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Uploads multisite (sous-répertoires) : route via WordPress
RewriteRule ^wp-content/uploads/(.*)$ wp-includes/ms-files.php?file=$1 [L]
# Tout le reste vers WordPress
RewriteRule . index.php [L]
wp-config.php : base + Multisite + durcissement léger
Extrait “complet” (hors clés uniques) centré sur Multisite. Ne copiez pas vos secrets dans un article : gardez vos propres AUTH_KEY etc. Référence : wp-config.php.
<?php
// --- Base de données ---
define( 'DB_NAME', 'wp_db' );
define( 'DB_USER', 'wp_user' );
define( 'DB_PASSWORD', 'changez-moi' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
// Préfixe (attention : en Multisite, il reste unique pour le réseau)
$table_prefix = 'wp_';
// --- Debug (en staging, pas en prod) ---
// define( 'WP_DEBUG', true );
// define( 'WP_DEBUG_LOG', true );
// define( 'WP_DEBUG_DISPLAY', false );
// --- Durcissement raisonnable ---
define( 'DISALLOW_FILE_EDIT', true ); // Évite l'éditeur de fichiers dans l'admin
// --- Autorise l'écran d'installation Multisite (optionnel après setup) ---
define( 'WP_ALLOW_MULTISITE', true );
// --- Multisite ---
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', true );
define( 'DOMAIN_CURRENT_SITE', 'example.com' );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );
// Si vous êtes derrière un reverse proxy qui termine le TLS
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
$_SERVER['HTTPS'] = 'on';
}
// --- Mémoire PHP (si vous maîtrisez votre hébergement) ---
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
/* C'est tout, ne touchez pas à ce qui suit ! */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
require_once ABSPATH . 'wp-settings.php';
php.ini (ou conf PHP-FPM) : paramètres utiles Multisite
Sur Multisite, les limites d’upload et de temps d’exécution sont les premières causes de “ça plante quand j’upload un thème sur le réseau”. Exemple minimal (adaptez à votre stack) :
; Exemple : /etc/php/8.3/fpm/conf.d/99-wordpress.ini
memory_limit = 512M
upload_max_filesize = 128M
post_max_size = 128M
max_execution_time = 120
max_input_time = 120
max_input_vars = 5000
; Sécurité
expose_php = Off
Vérification
Vérifier la résolution DNS et le TLS
# DNS
dig +short example.com
dig +short site1.example.com
# TLS + Host correct
curl -I https://example.com/
curl -I https://site1.example.com/
Vérifier que WordPress “voit” le réseau
cd /var/www/example.com/public
# Affiche des infos réseau si Multisite actif
wp core is-installed
wp site list
Vérifier les réécritures (symptômes typiques)
- Si
/wp-adminredirige en boucle : problème de HTTPS/headers proxy ou desiteurl. - Si un sous-site renvoie 404 sur toutes les pages sauf la home : rewrite Nginx/Apache incorrect, ou
try_filesabsent. - Si les médias 404 : règles uploads Multisite manquantes, ou permissions/chemins.
Test MySQL ciblé
mysql -u'wp_user' -p'wp_pass' wp_db -e "
SELECT blog_id, domain, path, public, archived, deleted, spam
FROM wp_blogs
ORDER BY blog_id ASC
LIMIT 20;
"
Si ça ne marche pas
Quand Multisite casse, le bon réflexe est de diagnostiquer du bas vers le haut : DNS → TLS → vhost → PHP-FPM → WordPress → cache.
Tableau de diagnostic (symptômes réels)
| Symptôme | Cause probable | Vérification | Solution |
|---|---|---|---|
| Un sous-domaine affiche le site principal | DNS wildcard absent ou vhost non wildcard | dig site2.example.com, nginx -T | grep server_name |
Ajouter *.example.com au DNS et au server_name |
| Redirection 301/302 en boucle sur /wp-admin | HTTPS mal détecté derrière proxy | curl -I et regarder Location: |
Configurer X-Forwarded-Proto + forcer $_SERVER['HTTPS']='on' si nécessaire |
| 404 sur toutes les pages des sous-sites | Règles rewrite manquantes / .htaccess ignoré | Apache: vérifier AllowOverride. Nginx: vérifier try_files |
Appliquer les règles Multisite correctes |
| Médias cassés (404 sur uploads) | Règles uploads Multisite absentes ou permissions | Tester un fichier direct + logs Nginx/Apache | Ajouter règles uploads + corriger permissions |
| Le domaine B sert le contenu du domaine A | Cache serveur ne varie pas par Host | Headers cache + inspection config cache | Inclure $host dans la clé de cache, purger |
Logs à lire (au bon endroit)
# Nginx
tail -n 200 /var/log/nginx/example.com.error.log
tail -n 200 /var/log/nginx/example.com.access.log
# PHP-FPM (chemin variable selon distro)
tail -n 200 /var/log/php8.3-fpm.log
# WordPress debug log (si activé)
tail -n 200 /var/www/example.com/public/wp-content/debug.log
Vérifier les permissions (uploads, upgrades)
Une permission trop stricte casse les uploads, une permission trop large vous expose. Un compromis courant : dossiers 755, fichiers 644, propriétaire = user du pool PHP-FPM.
cd /var/www/example.com/public
# Adaptez www-data au user de votre serveur/PHP-FPM
chown -R www-data:www-data .
find . -type d -exec chmod 755 {} ;
find . -type f -exec chmod 644 {} ;
Pièges et erreurs courantes
| Erreur | Cause | Solution |
|---|---|---|
| Coller les constantes Multisite après “stop editing” | WordPress ne lit pas la config | Déplacer les define() avant la fin du fichier |
| Oublier le wildcard DNS en sous-domaines | Les sous-sites ne résolvent pas | Ajouter *.domaine côté DNS + vhost |
| Tester en production sans backup/restauration | Retour arrière impossible | Dump SQL + archive fichiers + test de restore |
| Cache Nginx qui ne varie pas par Host | Clé de cache incomplète | Inclure $host dans la clé, purger |
| Permaliens “cassés” après migration | Rewrite côté serveur non aligné | Vérifier try_files/.htaccess + purger caches |
| Utiliser un vieux snippet trouvé en 2017 | Hypothèses obsolètes (PHP, proxy, sécurité) | Revenir à la doc officielle WP 6.9.x + adapter à PHP 8.1+ |
| Uploads 413 Request Entity Too Large | Limite Nginx/PHP | client_max_body_size + upload_max_filesize/post_max_size |
| Snippet cassé par un plugin de snippets | Erreur de syntaxe (point-virgule, parenthèse) | Déployer via Git/SSH, valider php -l avant |
Sécurité serveur
Un Multisite augmente l’impact d’une faille : un plugin vulnérable activé en réseau touche tous les sites. Côté serveur, je verrouille systématiquement trois zones : exécution PHP dans uploads, endpoints sensibles, et headers.
Bloquer PHP dans uploads (Nginx/Apache)
Vous avez déjà vu la règle Nginx plus haut. Pour Apache, ajoutez ceci dans un vhost ou un .htaccess dans wp-content/uploads (si AllowOverride le permet). Risque : si un attaquant upload un .php, il ne doit jamais être exécuté.
# /var/www/example.com/public/wp-content/uploads/.htaccess
<FilesMatch ".php$">
Require all denied
</FilesMatch>
Headers HTTP (base)
Évitez de surcharger avec une CSP “copier-coller” qui casse Elementor/Divi/Avada. Commencez par des headers sûrs et non intrusifs.
# Extraits Nginx (déjà partiellement inclus plus haut)
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
Isolation et droits admin réseau
- Limitez le nombre de super-admins. C’est l’équivalent root côté WordPress.
- Évitez d’activer en réseau des plugins “utilitaires” non critiques (constructeurs, sliders, etc.).
- Si vous hébergez des clients, séparez les environnements (staging/prod) au niveau DNS + vhosts + bases.
Ressources
- Developer Resources : Multisite (Advanced Administration)
- Multisite : Installation
- wp-config.php : API et constantes
- WP-CLI : commande wp site
- WordPress.org Documentation : Create a Network
- GitHub : WordPress Core (wordpress-develop)
- WordPress Core Trac
- PHP.net : directives php.ini (core)
FAQ
Peut-on convertir un site existant en Multisite sans le casser ?
Oui, mais faites-le d’abord en staging. Le point de rupture le plus fréquent est le rewrite serveur (404) et la détection HTTPS (boucles). Sauvegardez, activez Multisite, appliquez les règles, puis testez.
Sous-domaines ou sous-répertoires pour un réseau de clients ?
Dans mon expérience, sous-domaines + domain mapping est plus propre à long terme. Sous-répertoires est plus simple au départ, mais vous finissez souvent par vouloir des domaines dédiés.
Est-ce que WP-CLI est obligatoire ?
Non, mais dès que vous migrez/restaurez, WP‑CLI vous évite des erreurs manuelles. Rien que wp site list et wp search-replace --network valent l’installation.
Comment éviter que le cache serveur mélange les sites ?
Assurez-vous que la clé de cache varie par Host. Sur Nginx, une clé de cache sans $host est un anti-pattern en Multisite. Purgez ensuite le cache.
Pourquoi mes médias sont en 404 après passage en Multisite ?
Le plus souvent : règles de rewrite incomplètes (Apache) ou try_files manquant (Nginx), ou bien un blocage de permissions. Vérifiez aussi que vous ne bloquez pas accidentellement /wp-content/uploads/sites/.
Peut-on avoir un site du réseau sur un autre serveur ?
Pas “nativement” avec un seul cœur WordPress. Multisite suppose une base et un code partagés. Vous pouvez externaliser des médias (S3) ou mettre un CDN, mais pas déplacer un sous-site isolément sans le sortir du réseau.
Comment cloner un seul sous-site vers un site standalone ?
C’est une extraction : export des tables du blog (wp_12_*), export des uploads du site (uploads/sites/12), puis réécriture des URLs. Faites-le avec WP‑CLI et un script SQL, sinon vous oublierez des références sérialisées.
Que faire si un plugin doit être actif partout ?
Activez-le en réseau si c’est réellement nécessaire (sécurité, cache objet, SEO “global”). Sinon, activez par site pour réduire le blast radius d’un bug.
Divi 5 / Elementor / Avada posent-ils des problèmes en Multisite ?
Techniquement non, mais opérationnellement oui : mises à jour globales, licences, et bibliothèques partagées. Gardez un staging et évitez l’activation réseau par réflexe.
Comment vérifier rapidement si je suis bien en Multisite ?
wp site list doit fonctionner, et dans wp-config.php vous devez avoir define('MULTISITE', true). Côté admin, vous devez voir “Mes sites”.
Quel est le piège numéro 1 en migration ?
Modifier des domaines dans le contenu sans mettre à jour wp_blogs/wp_site, ou inversement. Faites les deux, et faites un --dry-run avant toute réécriture massive.