WordPress : changer de domaine proprement avec WP-CLI

Credit : Logo officiel

WordPress : changer de domaine proprement avec WP-CLI

Dylan D. — Agent Support Technique Serveur WordPress 1820 mots 10 min de lecture

WordPress : changer de domaine proprement avec WP-CLI

Mercredi apres-midi, un client e-commerce nous appelle parce que sa migration de domaine a tourne au cauchemar. Il avait son site WordPress 6.4 sur boutique-truc.fr et voulait passer sur boutique-truc.com apres acquisition. Son developpeur a fait un simple UPDATE wp_options SET option_value = REPLACE(...) en SQL pur. Resultat : le site ouvre, mais les widgets ont disparu, le slider d'accueil est casse, le theme a perdu sa config, et les liens internes pointent vers boutique-truc.frcom. Trois heures plus tard, restauration depuis backup et migration refaite avec wp search-replace. Cinq minutes propre.

Changer de nom de domaine sur WordPress, ou passer de HTTP a HTTPS, c'est une etape critique mais qu'on rate facilement. Mal fait, ca casse le site silencieusement (les options sont cassees mais le site charge quand meme). Bien fait avec WP-CLI, c'est propre et rapide. Je te montre la methode complete que j'utilise sur les migrations IONOS.

Pourquoi pas un simple SQL REPLACE ?

C'est l'erreur numero 1 que je vois. Quelqu'un de pas familier avec WordPress se dit "je vais juste faire un REPLACE en SQL" :

-- NE FAITES PAS CA
UPDATE wp_options SET option_value = REPLACE(option_value, 'ancien-domaine.fr', 'nouveau-domaine.fr');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'ancien-domaine.fr', 'nouveau-domaine.fr');

Le probleme c'est que WordPress stocke beaucoup de donnees serialisees (PHP serialize) dans la base : options des plugins, widgets, Customizer, configurations de theme, settings WooCommerce, et tout un tas d'autres trucs. Un REPLACE SQL casse la serialisation parce qu'il modifie la valeur sans recalculer la longueur.

Exemple concret. La donnee serialisee :

s:24:"http://ancien-domaine.fr"

Le s:24 indique que la chaine fait 24 caracteres. Si tu remplaces par un domaine plus long :

s:24:"http://nouveau-domaine.fr"  # FAUX !

La longueur ne correspond plus a la chaine, PHP ne peut plus deserialiser. Resultat :

La version correcte aurait du etre s:25 apres le replace, mais SQL ne peut pas calculer ca.

La bonne methode avec WP-CLI

wp search-replace 'https://ancien-domaine.fr' 'https://nouveau-domaine.fr' --skip-columns=guid

WP-CLI gere automatiquement la serialisation. Il deserialise les donnees, fait le remplacement, recalcule les longueurs, et re-serialise correctement. Le bon outil pour le bon job.

Pourquoi --skip-columns=guid

Le champ guid dans wp_posts c'est un identifiant unique permanent assigne a chaque article, page, et media a sa creation. Selon la documentation officielle WordPress, il ne doit jamais etre modifie apres publication.

Si tu changes les GUID :

On voit regulierement des clients qui font le search-replace sans --skip-columns=guid et qui se demandent pourquoi leur flux RSS reenvoit tout. Le guid est techniquement une URL mais sert d'identifiant -- WordPress ne l'utilise jamais pour generer des liens reels.

Procedure complete pas a pas

1. Backup obligatoire

Avant tout, backup complet :

wp db export /home/htdocs/backups/avant-migration-$(date +%Y%m%d-%H%M).sql

Et backup des fichiers pour le worst case :

tar -czf /home/htdocs/backups/files-$(date +%Y%m%d).tar.gz /home/htdocs/web/

2. Dry-run obligatoire

WP-CLI a une option dry-run qui simule sans rien modifier. Toujours la lancer avant le vrai run :

wp search-replace 'https://ancien-domaine.fr' 'https://nouveau-domaine.fr' --skip-columns=guid --dry-run

La sortie te dit combien de remplacements seraient faits dans chaque table :

Table           Column         Replacements
wp_options      option_value   42
wp_postmeta     meta_value     156
wp_posts        post_content   89
wp_comments     comment_content 12
...

Verifie que les chiffres ont du sens. Si t'as 0 remplacement partout, c'est que tu cherches le mauvais domaine. Si tu en as 50 000, soit ton site est tres lie au domaine, soit y'a un truc anormal.

3. Executer le replace

wp search-replace 'https://ancien-domaine.fr' 'https://nouveau-domaine.fr' --skip-columns=guid

WP-CLI affiche le meme tableau que le dry-run mais avec les vrais remplacements effectues.

4. Verifier les options principales

wp option get siteurl
wp option get home

Les deux doivent retourner le nouveau domaine. Si pas le cas (ca arrive avec certaines configs custom) :

wp option update siteurl 'https://nouveau-domaine.fr'
wp option update home 'https://nouveau-domaine.fr'

5. Vider tous les caches

wp cache flush
wp rewrite flush

Si tu as un plugin de cache (W3 Total Cache, WP Super Cache, WP Rocket, LiteSpeed) :

wp w3-total-cache flush all
wp super-cache flush
wp rocket clean --confirm
wp litespeed-purge all

Selon ton plugin, la commande varie. Au pire, va dans le BO et purge le cache manuellement.

Migration HTTP vers HTTPS

Sur les serveurs IONOS, quand un client active le SSL Let's Encrypt sur son domaine, faut basculer toutes les URLs en HTTPS. La methode est identique :

wp search-replace 'http://monsite.fr' 'https://monsite.fr' --skip-columns=guid

Pense aussi aux variantes avec/sans www :

wp search-replace 'http://www.monsite.fr' 'https://www.monsite.fr' --skip-columns=guid
wp search-replace 'http://monsite.fr' 'https://monsite.fr' --skip-columns=guid

L'ordre compte ! Fais d'abord le www. puis le sans-www. Sinon le second remplace les http://monsite.fr (qui font partie de http://www.monsite.fr apres ton premier replace).

Pour eviter les contenus mixtes (HTTPS qui charge du HTTP), force aussi dans le contenu :

wp search-replace 'src="http://' 'src="//' --skip-columns=guid
wp search-replace 'href="http://' 'href="//' --skip-columns=guid

Le // (protocol-relative URL) s'adapte au protocole de la page. Mais c'est decourage en 2026, prefere des URLs https:// explicites.

Migration multisite

Si t'as un WordPress multisite, le wp search-replace marche differemment :

wp search-replace 'https://ancien.fr' 'https://nouveau.fr' --skip-columns=guid --network --url=https://ancien.fr

L'option --network itere sur tous les sites du reseau. L'--url precise sur quel site se baser pour le contexte initial.

Faut aussi mettre a jour wp_blogs :

wp db query "UPDATE wp_blogs SET domain = 'nouveau.fr' WHERE domain = 'ancien.fr'"

Et wp_site :

wp db query "UPDATE wp_site SET domain = 'nouveau.fr' WHERE domain = 'ancien.fr'"

Verification post-migration

Une fois la migration faite, audit complet pour s'assurer qu'il ne reste pas de traces de l'ancien domaine :

wp db search 'ancien-domaine.fr' --stats

L'option --stats te dit combien d'occurrences restent dans chaque table. Idealement zero.

Pour identifier ou il reste des occurrences :

wp db search 'ancien-domaine.fr' --table=wp_options
wp db search 'ancien-domaine.fr' --table=wp_postmeta

Il reste souvent des URLs codees en dur dans les fichiers du theme (header.php, footer.php) ou dans du CSS custom. Le search-replace touche que la base de donnees. Pour les fichiers :

grep -r 'ancien-domaine.fr' /home/htdocs/web/wp-content/themes/
grep -r 'ancien-domaine.fr' /home/htdocs/web/wp-content/uploads/ --include="*.css" --include="*.js"

Migration depuis un autre hebergeur

Quand tu migres un site WordPress depuis un autre hebergeur vers IONOS, tu fais souvent un changement de domaine en plus du changement d'hebergement. La sequence complete :

# 1. Sur l'ancien hebergeur, exporter
wp db export old-site.sql
tar -czf old-files.tar.gz wp-content/

# 2. Transferer vers IONOS
scp old-site.sql old-files.tar.gz user@nouveau-serveur:/home/htdocs/

# 3. Sur IONOS, importer la base et les fichiers
cd /home/htdocs/web/
tar -xzf ../old-files.tar.gz
wp db import ../old-site.sql

# 4. Mettre a jour les URLs
wp search-replace 'https://ancien-domaine.fr' 'https://nouveau-domaine.fr' --skip-columns=guid

# 5. Mettre a jour les options critiques
wp option update siteurl 'https://nouveau-domaine.fr'
wp option update home 'https://nouveau-domaine.fr'

# 6. Vider tous les caches
wp cache flush
wp rewrite flush

Si tu dois garder l'ancien domaine en place le temps de la propagation DNS, edite ton /etc/hosts local pour pointer le nouveau domaine vers la nouvelle IP avant le changement DNS public.

Mettre a jour les redirections 301

Apres une migration de domaine, configure des redirections 301 de l'ancien vers le nouveau pour preserver le SEO. Dans le .htaccess Apache :

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?ancien-domaine\.fr [NC]
RewriteRule ^(.*)$ https://nouveau-domaine.fr/$1 [R=301,L]

En Nginx :

server {
    listen 80;
    listen 443 ssl;
    server_name ancien-domaine.fr www.ancien-domaine.fr;
    return 301 https://nouveau-domaine.fr$request_uri;
}

Les 301 doivent rester en place plusieurs mois (idealement un an) pour que Google transfere completement le "juice" SEO.

Tester avant de basculer le DNS

Avant de pointer le DNS public sur le nouveau serveur, teste localement en modifiant ton /etc/hosts :

sudo nano /etc/hosts

Ajoute :

195.181.123.45  nouveau-domaine.fr
195.181.123.45  www.nouveau-domaine.fr

L'IP est celle de ton serveur IONOS. Maintenant ton navigateur resout nouveau-domaine.fr vers ce serveur, alors que tout le reste du monde voit encore l'ancien. Tu peux tester completement avant de switcher le DNS public.

Une fois le test OK, change le DNS chez ton registrar. Le TTL est generalement de 3600 secondes (1 heure), donc compte 1-4h pour la propagation complete dans le monde.

N'oublie pas de retirer la ligne du /etc/hosts apres pour que tu vois le DNS reel comme tes visiteurs.

Erreurs courantes et leur fix

"Could not connect to database"

WP-CLI lit wp-config.php pour les credentials. Si le wp-config est casse ou que le user MySQL n'a pas les bons droits, ca plante. Verifie :

wp db check

"Cannot redeclare wp_*" pendant le replace

Un plugin pete pendant l'execution. Desactive temporairement :

wp plugin deactivate --all
wp search-replace ...
wp plugin activate --all

Site casse apres le replace

Restaure le backup :

wp db import /home/htdocs/backups/avant-migration-XXX.sql

Puis investigue. Souvent c'est qu'un plugin stocke des donnees serialisees d'une facon non-standard.

Le replace tourne pendant des heures

Sur des grosses bases (5+ Go), ca peut etre tres long. Ajoute --all-tables si tu as des tables custom non-prefixees :

wp search-replace ... --all-tables

Ou cible juste les tables pertinentes :

wp search-replace ... wp_options wp_postmeta wp_posts

Liens images casses apres migration

Les uploads referencent souvent l'ancien URL. Force le replace dans postmeta :

wp search-replace 'wp-content/uploads' 'wp-content/uploads' --regex --regex-flags=u

Et regenere les thumbnails :

wp media regenerate --yes

Pour aller plus loin

Migration reussie, donnees preservees

WP-CLI 2.10 a ameliore la gestion des serialisations imbriquees, donc si tu avais des soucis avec les anciennes versions, retentes maintenant. Le wp search-replace est l'outil canonique pour toute manipulation d'URL en base WordPress. Apprends a l'utiliser, fais toujours un dry-run d'abord, et garde tes backups.

La migration de domaine c'est pas juste "changer le nom". C'est preserver les options, garder les widgets, conserver les configurations de plugins, maintenir le SEO via 301, et bien sur eviter les contenus mixtes en HTTPS. Avec la methode WP-CLI, tu fais ca proprement en 5 minutes au lieu d'y passer une journee a tout reparer apres une migration cassee. Ton client te remerciera, et toi tu pourras passer aux migrations suivantes en confiance.

# Articles similaires

Sur les memes sujets et plus loin