Migrer son site WordPress d'un hébergeur mutualisé vers un VPS
Votre site WordPress a grandi. Le mutualisé qui suffisait au lancement montre ses limites : temps de réponse en dents de scie aux heures de pointe, impossibilité d'installer Redis ou de choisir sa version de PHP, limite de processus qui fait tomber le site à la première campagne un peu réussie. Passer sur un VPS règle tout cela, à condition de mener la migration proprement.
Ce guide couvre la migration complète et sans coupure visible d'un site WordPress depuis n'importe quel hébergement mutualisé (cPanel, Plesk, o2switch, OVH, Ionos, Hostinger…) vers un VPS Debian 12 avec Nginx, PHP-FPM et MariaDB. Le principe clé : on monte le nouveau serveur entièrement, on le teste avec le vrai site, et on ne bascule les DNS qu'à la toute fin.
Faut-il vraiment migrer sur un VPS ?
Soyons honnêtes : un VPS demande de l'administration. Mises à jour système, sécurité, sauvegardes : c'est vous qui les gérez. En échange, vous obtenez des ressources garanties et un contrôle total.
| Hébergement mutualisé | VPS | |
|---|---|---|
| Ressources | Partagées avec des dizaines de sites | Garanties (CPU, RAM, disque) |
| Stack | Imposée (Apache, PHP fourni) | Libre (Nginx, PHP 8.3, Redis, cache serveur…) |
| Administration | Gérée par l'hébergeur | À votre charge |
| Emails | Généralement inclus | À prévoir séparément |
| Idéal pour | Site vitrine, blog modeste | Site à trafic, WooCommerce, multi-sites, agences |
Si ce qui vous pousse à quitter votre hébergeur est sa lenteur ou son support, et non un besoin de contrôle technique, l'Hébergement Web cPanel YorkHost est peut-être la bonne réponse : SSL offert, Anti-DDoS inclus, emails professionnels, sans avoir à administrer un serveur. Ce guide reste utile pour ceux qui veulent la maîtrise complète d'un VPS.
Prérequis
- Un VPS Linux YorkHost sous Debian 12, avec accès root. Pour un WordPress classique, un VPS-4 (2 vCores, 4 Go) suffit ; pour WooCommerce ou un site à fort trafic, visez un VPS-8 minimum.
- Un accès à votre hébergement actuel : panneau (cPanel, Plesk…), FTP/SFTP et phpMyAdmin
- L'accès à la zone DNS de votre nom de domaine (chez votre registrar ou votre hébergeur)
- SSH configuré et sécurisé sur le VPS, UFW actif avec les ports 22, 80 et 443 ouverts
Étape 1 : Auditer le site existant
Avant de toucher à quoi que ce soit, notez ce que vous migrez. Cinq minutes ici évitent des heures de débogage plus tard.
Dans l'administration WordPress, Outils → Santé du site → Informations, relevez :
- La version de PHP utilisée (vous installerez la même ou une plus récente compatible)
- La version de WordPress et la taille du répertoire
wp-content/uploads - Le préfixe des tables et le nom de la base (visibles dans
wp-config.php) - La liste des extensions actives, en particulier celles liées au cache (WP Rocket, LiteSpeed Cache, W3 Total Cache) et à la sécurité (Wordfence, iThemes), qui ont souvent des réglages spécifiques à l'hébergeur
Vérifiez aussi que le site n'utilise pas de fonctionnalités propres à l'hébergeur : cron « réel » configuré dans le panneau, tâches planifiées, redirections dans .htaccess (Nginx n'utilise pas .htaccess, nous les réécrirons), certificat SSL spécifique.
La plupart des mutualisés incluent des boîtes mail. Un VPS ne les remplace pas : héberger un serveur mail soi-même est un métier à part. Avant de résilier l'ancien hébergement, décidez où vivront vos adresses (offre mail de votre registrar, emails professionnels de l'hébergement web YorkHost, Google Workspace…). Pour les emails envoyés par WordPress (notifications, commandes WooCommerce), utilisez une extension SMTP (WP Mail SMTP, FluentSMTP) avec un vrai service d'envoi plutôt que le mail() de PHP, qui finit en spam.
Étape 2 : Exporter le site
Deux choses à récupérer : les fichiers et la base de données.
Les fichiers
Depuis le gestionnaire de fichiers de votre panneau ou via FTP, récupérez l'intégralité du répertoire du site (souvent public_html/ ou www/). Sur cPanel, Sauvegarde → Télécharger une sauvegarde du répertoire personnel produit une archive .tar.gz bien plus rapide à transférer que des milliers de fichiers en FTP.
Si votre hébergeur donne un accès SSH, c'est encore plus simple, tout se fait en une commande depuis le VPS (voir étape 4).
La base de données
Via phpMyAdmin : sélectionnez la base, onglet Exporter, méthode Personnalisée, format SQL, cochez Ajouter l'instruction DROP TABLE, et enregistrez le fichier. Pour une base de plusieurs centaines de Mo, activez la compression gzip.
Si vous avez SSH sur l'ancien hébergement :
mysqldump -u UTILISATEUR -p --single-transaction --default-character-set=utf8mb4 NOM_BASE | gzip > wordpress.sql.gz
Duplicator, All-in-One WP Migration ou UpdraftPlus fonctionnent très bien et automatisent une partie de ce guide. Leur limite : les versions gratuites plafonnent souvent la taille (512 Mo pour All-in-One), et elles masquent ce qui se passe, ce qui complique le diagnostic en cas de problème. La méthode manuelle décrite ici marche pour un site de 50 Mo comme de 50 Go, et vous comprendrez votre serveur à la fin.
Étape 3 : Préparer le VPS
Installer la stack
sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx mariadb-server php-fpm php-mysql php-curl php-gd php-intl php-mbstring php-xml php-zip php-imagick php-bcmath unzip rsync
Sur Debian 12, cela installe PHP 8.2, compatible avec toutes les versions récentes de WordPress. Si vous avez besoin de PHP 8.3 ou 8.4, ajoutez le dépôt Sury :
sudo apt install -y apt-transport-https lsb-release ca-certificates curl
curl -fsSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt update
sudo apt install -y php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-intl php8.3-mbstring php8.3-xml php8.3-zip php8.3-imagick php8.3-bcmath
Dans la suite du guide, remplacez php8.2-fpm par la version installée.
Sécuriser MariaDB et créer la base
sudo mysql_secure_installation
Répondez oui à tout (mot de passe root, suppression des utilisateurs anonymes et de la base de test). Puis créez la base et l'utilisateur, en reprenant exactement le même nom de base et le même préfixe que sur l'ancien hébergement pour ne rien avoir à modifier dans wp-config.php :
sudo mysql
CREATE DATABASE monsite_wp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'monsite'@'localhost' IDENTIFIED BY 'un-mot-de-passe-fort';
GRANT ALL PRIVILEGES ON monsite_wp.* TO 'monsite'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Régler PHP-FPM pour WordPress
Les valeurs par défaut sont trop basses pour un site avec des médias :
sudo nano /etc/php/8.2/fpm/php.ini
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 120
max_input_vars = 3000
Et dimensionnez le pool selon la RAM du VPS (chaque processus PHP consomme 30 à 60 Mo) :
sudo nano /etc/php/8.2/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 20 # VPS-4 : ~12, VPS-8 : ~20, VPS-16 : ~40
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
sudo systemctl restart php8.2-fpm
Installer WP-CLI
WP-CLI est l'outil en ligne de commande de WordPress. Il rendra la suite beaucoup plus rapide :
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info
Étape 4 : Transférer les fichiers
Créez le répertoire du site et donnez-le à l'utilisateur de Nginx/PHP :
sudo mkdir -p /var/www/monsite.fr
sudo chown -R www-data:www-data /var/www/monsite.fr
Option A : rsync depuis l'ancien hébergement (si vous avez SSH)
C'est la méthode la plus fiable : elle reprend là où elle s'est arrêtée si le transfert coupe, et vous pouvez la relancer pour synchroniser les derniers changements juste avant la bascule.
sudo rsync -avz --progress -e "ssh -p 22" ancien_user@ancien-hebergeur.fr:~/public_html/ /var/www/monsite.fr/
Option B : uploader l'archive
Depuis votre ordinateur, envoyez l'archive téléchargée à l'étape 2 :
scp backup-monsite.tar.gz root@IP_DU_VPS:/tmp/
Puis sur le VPS :
cd /tmp && tar -xzf backup-monsite.tar.gz
# Adaptez le chemin selon la structure de l'archive (souvent homedir/public_html)
sudo rsync -a /tmp/homedir/public_html/ /var/www/monsite.fr/
Vous pouvez aussi utiliser un client SFTP graphique, voir SFTP avec VSCode.
Permissions
sudo chown -R www-data:www-data /var/www/monsite.fr
sudo find /var/www/monsite.fr -type d -exec chmod 755 {} \;
sudo find /var/www/monsite.fr -type f -exec chmod 644 {} \;
sudo chmod 600 /var/www/monsite.fr/wp-config.php
Étape 5 : Importer la base de données
Envoyez le dump sur le VPS puis importez-le :
scp wordpress.sql.gz root@IP_DU_VPS:/tmp/
gunzip < /tmp/wordpress.sql.gz | sudo mysql monsite_wp
Vérifiez que les tables sont là :
sudo mysql -e "USE monsite_wp; SHOW TABLES;" | head
Mettre à jour wp-config.php
Ouvrez /var/www/monsite.fr/wp-config.php et vérifiez ces lignes. Si vous avez repris les mêmes noms, seul le mot de passe change :
define( 'DB_NAME', 'monsite_wp' );
define( 'DB_USER', 'monsite' );
define( 'DB_PASSWORD', 'un-mot-de-passe-fort' );
define( 'DB_HOST', 'localhost' );
Profitez-en pour ajouter, si elles n'y sont pas :
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'DISALLOW_FILE_EDIT', true ); // désactive l'éditeur de fichiers dans l'admin
define( 'FS_METHOD', 'direct' );
Testez que WordPress parle bien à la base :
cd /var/www/monsite.fr
sudo -u www-data wp db check
sudo -u www-data wp option get siteurl
Étape 6 : Configurer Nginx
Nginx ne lit pas .htaccess. Voici une configuration complète et éprouvée pour WordPress :
sudo nano /etc/nginx/sites-available/monsite.fr
server {
listen 80;
listen [::]:80;
server_name monsite.fr www.monsite.fr;
root /var/www/monsite.fr;
index index.php index.html;
client_max_body_size 64M;
# Journaux
access_log /var/log/nginx/monsite.fr.access.log;
error_log /var/log/nginx/monsite.fr.error.log;
# Permaliens WordPress
location / {
try_files $uri $uri/ /index.php?$args;
}
# PHP via PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 120;
}
# Cache navigateur pour les fichiers statiques
location ~* \.(jpg|jpeg|png|gif|webp|avif|svg|ico|css|js|woff2?|ttf)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# Sécurité : bloque l'exécution de PHP dans uploads et l'accès aux fichiers sensibles
location ~* /wp-content/uploads/.*\.php$ { deny all; }
location ~ /\.(?!well-known) { deny all; }
location = /xmlrpc.php { deny all; }
location ~* (readme\.html|license\.txt|wp-config\.php) { deny all; }
}
Activez le site :
sudo ln -s /etc/nginx/sites-available/monsite.fr /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
Si votre ancien .htaccess contenait des redirections personnalisées (Redirect 301 /ancienne-page /nouvelle-page), convertissez-les en blocs Nginx dans le server : location = /ancienne-page { return 301 /nouvelle-page; }. Les règles standard de WordPress sont déjà couvertes par le try_files.
Étape 7 : Tester avant de basculer les DNS
C'est l'étape qui rend la migration sans risque. Vous allez faire croire à votre ordinateur seul que monsite.fr pointe déjà sur le VPS, pendant que le reste du monde continue de voir l'ancien hébergement.
Éditez le fichier hosts de votre machine :
- Windows :
C:\Windows\System32\drivers\etc\hosts(ouvrir le Bloc-notes en administrateur) - macOS / Linux :
sudo nano /etc/hosts
Ajoutez :
IP_DU_VPS monsite.fr www.monsite.fr
Ouvrez http://monsite.fr dans un navigateur en navigation privée. Vous devez voir votre site servi par le VPS (vérifiez avec les outils de développement : l'en-tête Server: nginx au lieu d'Apache ou LiteSpeed). Parcourez les pages, connectez-vous à l'administration, uploadez une image, testez un formulaire de contact, passez une commande test si c'est du WooCommerce.
Les problèmes se règlent maintenant, tranquillement, sans aucun impact pour vos visiteurs.
Si le site change aussi d'adresse (par exemple monsite.ancien-hebergeur.fr → monsite.fr), remplacez l'ancienne URL partout dans la base avec WP-CLI, qui gère correctement les données sérialisées, contrairement à un rechercher-remplacer SQL brut :
cd /var/www/monsite.fr
sudo -u www-data wp search-replace 'https://ancien-domaine.fr' 'https://monsite.fr' --all-tables --precise
Ajoutez --dry-run d'abord pour voir ce qui serait modifié.
Étape 8 : Basculer les DNS
Une fois le site validé sur le VPS :
- Abaissez le TTL de vos enregistrements DNS à 300 secondes, idéalement 24 h avant la bascule, pour que le changement se propage vite. Si ce n'est pas fait, ce n'est pas bloquant, la propagation prendra simplement plus longtemps.
- Si vous avez SSH sur l'ancien hébergement, faites une dernière synchronisation des fichiers et de la base (articles publiés, commandes passées entre-temps) : relancez le
rsyncet réimportez un dump frais. - Modifiez les enregistrements :
| Type | Nom | Valeur | TTL |
|---|---|---|---|
| A | @ | IP_DU_VPS | 300 |
| A | www | IP_DU_VPS | 300 |
- Retirez la ligne ajoutée dans votre fichier
hosts. - Vérifiez la propagation avec
dig monsite.fr +shortou dnschecker.org.
Gardez-le actif au moins deux semaines. Cela couvre les caches DNS récalcitrants, et vous permet de récupérer un fichier oublié. Passez l'ancien site en maintenance ou en lecture seule pendant ce temps pour éviter que des contenus y soient encore créés par erreur.
Étape 9 : Activer HTTPS
Dès que le domaine pointe sur le VPS, obtenez un certificat Let's Encrypt :
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d monsite.fr -d www.monsite.fr
Choisissez la redirection automatique HTTP → HTTPS. Certbot modifie la configuration Nginx et installe un timer de renouvellement automatique. Vérifiez-le :
sudo certbot renew --dry-run
Mettez ensuite à jour les URL de WordPress si elles étaient encore en http:// :
cd /var/www/monsite.fr
sudo -u www-data wp option update home 'https://monsite.fr'
sudo -u www-data wp option update siteurl 'https://monsite.fr'
sudo -u www-data wp search-replace 'http://monsite.fr' 'https://monsite.fr' --all-tables --precise
Étape 10 : Finitions pour un site rapide et sûr
Cron WordPress fiable
Par défaut, WordPress lance ses tâches planifiées à chaque visite, ce qui est peu fiable et coûteux. Remplacez ce mécanisme par un vrai cron :
// wp-config.php
define( 'DISABLE_WP_CRON', true );
sudo crontab -u www-data -e
*/5 * * * * cd /var/www/monsite.fr && /usr/local/bin/wp cron event run --due-now --quiet
Voir le guide Cron jobs pour les détails.
Cache objet avec Redis
Un cache objet évite de re-interroger MariaDB pour les mêmes données à chaque page. Gain typique : 30 à 50 % de temps de génération en moins sur l'administration et WooCommerce.
sudo apt install -y redis-server php8.2-redis
sudo systemctl enable --now redis-server
sudo systemctl restart php8.2-fpm
Puis installez l'extension Redis Object Cache dans WordPress et activez-la.
Cache de page
Pour les visiteurs non connectés, un cache de page renvoie du HTML statique sans exécuter PHP. Deux options efficaces : une extension (WP Super Cache, Cache Enabler, ou WP Rocket en payant), ou le cache FastCGI de Nginx, plus performant mais un peu plus technique. Si vous utilisiez déjà une extension de cache sur le mutualisé, réactivez-la et purgez tout.
OPcache
Vérifiez qu'OPcache est actif (il l'est par défaut sur Debian) et augmentez sa mémoire pour WordPress :
sudo nano /etc/php/8.2/fpm/conf.d/10-opcache.ini
opcache.enable=1
opcache.memory_consumption=192
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
Protéger la page de connexion
Les tentatives de connexion par force brute sur wp-login.php sont permanentes sur tout site WordPress public. Une jail Fail2ban dédiée les bloque au niveau du firewall. La configuration complète est dans Fail2ban avancé. Ajoutez aussi une authentification à deux facteurs (extension Two Factor ou Wordfence).
Sauvegardes
Votre VPS YorkHost inclut des sauvegardes 7 jours glissants du disque complet, restaurables en un clic depuis l'espace client : un filet de sécurité précieux après une mise à jour qui tourne mal. Complétez-le par une sauvegarde applicative hors-site (fichiers + dump de la base) : c'est l'objet du guide Backup automatique offsite avec Restic ou Borg.
Checklist de migration
- Audit : version PHP, extensions, taille des uploads, cron, redirections
- Solution email décidée avant résiliation
- Fichiers et base exportés
- Stack installée, PHP-FPM dimensionné, base créée avec le même nom
- Fichiers transférés, permissions correctes
- Base importée,
wp db checkOK - Nginx configuré, redirections
.htaccessconverties - Site testé via le fichier
hosts: navigation, admin, upload, formulaires - TTL abaissé, dernière synchronisation, DNS basculés
- HTTPS actif, URLs en
https:// - Cron réel, Redis, cache de page, Fail2ban, sauvegardes hors-site
- Ancien hébergement conservé deux semaines, puis résilié
Dépannage
Page blanche ou erreur 500
Consultez /var/log/nginx/monsite.fr.error.log et /var/log/php8.2-fpm.log. Activez temporairement define( 'WP_DEBUG', true ); et define( 'WP_DEBUG_LOG', true ); dans wp-config.php : l'erreur apparaîtra dans wp-content/debug.log. Cause fréquente : une extension PHP manquante (php-intl, php-imagick) utilisée par un thème.
« Erreur lors de l'établissement de la connexion à la base de données »
Les identifiants dans wp-config.php ne correspondent pas à ceux créés dans MariaDB, ou DB_HOST pointe vers l'hôte de l'ancien hébergeur au lieu de localhost.
Les permaliens renvoient une 404
Le bloc location / { try_files ... } manque ou le site actif dans Nginx n'est pas le bon. sudo nginx -T | grep server_name liste les vhosts chargés. Réenregistrez ensuite les permaliens : Réglages → Permaliens → Enregistrer.
Boucle de redirection infinie
Souvent une extension de cache ou SSL (Really Simple SSL) configurée pour l'ancien hébergeur, ou un mélange http/https entre home, siteurl et la configuration Nginx. Désactivez les extensions via wp plugin deactivate --all, corrigez les URL, réactivez une par une.
Les images s'affichent mais l'upload échoue
Permissions : sudo chown -R www-data:www-data /var/www/monsite.fr/wp-content/uploads. Ou upload_max_filesize / client_max_body_size trop bas.
Le site est lent après migration
Avant d'accuser le serveur : htop pour voir si PHP ou MariaDB sature, puis Debug des performances. Neuf fois sur dix, un cache de page manquant ou une extension qui appelle un service externe à chaque page.
Nos VPS Linux sont livrés sur SSD Enterprise avec des processeurs Xeon cadencés au-delà de 3 GHz, ce qui compte pour PHP dont l'exécution est essentiellement monothread. L'Anti-DDoS multi-Tbps est inclus sans surcoût, tout comme les sauvegardes 7 jours, et notre support français répond en moins de 2 h en journée si vous bloquez sur une étape de cette migration.