Ce guide vous montre comment sortir un site WordPress d’un domaine additionnel pour le placer dans son propre compte cPanel, sur le même serveur. Un domaine additionnel, c’est un deuxième site hébergé à l’intérieur d’un compte cPanel existant, sous l’utilisateur Linux et le dossier personnel de ce compte. Les agences et les revendeurs arrivent là quand un client demande ses propres accès, ou quand il faut démêler un paquet de domaines avant une vente. La réponse courte tient en cinq parties. Vous copiez les fichiers et la base pendant que le site est encore en ligne. Vous retirez le domaine additionnel du compte d’origine, puis vous créez le nouveau compte avec ce domaine. Ensuite vous corrigez le propriétaire des fichiers pour le nouvel utilisateur Linux et vous rebranchez WordPress sur une base dont le nom a changé. À la fin, le site tourne sous son propre utilisateur Linux, avec sa base, son certificat, son courriel et ses tâches cron.
Ce que vous allez accomplir
- Sortir un domaine additionnel d’un compte cPanel partagé vers son propre compte sur le même serveur WHM, sans toucher aux autres sites.
- Déplacer les fichiers avec le bon propriétaire Linux, pour que les téléversements, les mises à jour et l’installation d’extensions continuent de marcher.
- Déplacer la base vers un nom qui porte le préfixe du nouveau compte, et pointer
wp-config.phpdessus. - Emporter ce qu’on laisse derrière sans s’en rendre compte : les comptes de courriel du domaine, les tâches cron et le certificat TLS.
- Résultat final : le client se connecte à son propre cPanel, ne voit que son site, et peut être suspendu, sauvegardé ou facturé à part.
Prérequis
- Un accès root à WHM (WebHost Manager, le panneau qui gère le serveur au-dessus des comptes cPanel). Un accès cPanel seul ne suffit pas, parce que créer un compte et changer le propriétaire des fichiers demandent tous deux le root.
- cPanel et WHM version 110 ou plus récent. Vérifiez avec
/usr/local/cpanel/cpanel -V. Les noms d’interface utilisés ici correspondent à la version 110 et aux suivantes. - Un accès au serveur en SSH (« secure shell », le terminal distant chiffré), en root.
- WP-CLI, l’outil WordPress en ligne de commande, disponible sous le nom
wp. Vérifiez avecwp --info. - De l’espace libre sur
/homed’au moins deux fois la taille du site, parce qu’à un moment deux copies coexistent. - Un forfait d’hébergement (cPanel l’appelle un « package ») sous lequel créer le nouveau compte. La liste est dans WHM → Packages → List Packages.
- Une fenêtre d’entretien. Le site est injoignable entre le moment où vous retirez le domaine additionnel et le moment où le nouveau compte le sert. Pour un petit site, ça se compte en minutes.
Dans tout ce qui suit, le compte d’origine est agencyco, le site déplacé est clientsite.com, et le nouveau compte sera clientsit.
Comment ça marche
Un compte cPanel est un utilisateur Linux. Tout ce qu’il contient appartient à cet utilisateur. Ça vaut pour les fichiers du dossier personnel, les bases de données (qui portent le nom du compte en préfixe), la boîte de courriel, la table cron et les certificats. Un domaine additionnel ne crée pas de nouvel utilisateur Linux. Il crée une deuxième racine de site dans le compte existant, alors clientsite.com est servi depuis /home/agencyco/public_html/clientsite.com et chaque fichier appartient à agencyco.
C’est pour ça que les outils de WHM qui traitent un compte entier ne conviennent pas ici. Le Transfer Tool et pkgacct empaquettent tout un compte pour le restaurer ailleurs, ce qui emporterait les autres sites de l’agence avec celui du client. Si vous déplacez plutôt un compte complet d’un serveur à un autre, servez-vous du Transfer Tool de WHM, qui est le bon outil pour ce travail-là.
Deux contraintes dictent l’ordre des étapes. D’abord, cPanel tient une seule carte des domaines et de leur compte propriétaire, dans /etc/userdomains. Il refuse de créer un compte pour un domaine qui y figure déjà, alors le domaine additionnel doit quitter le compte d’origine avant que le nouveau compte existe. Ensuite, cPanel ajoute le nom du compte en préfixe à chaque nom de base et d’utilisateur de base. Une base nommée agencyco_wp ne peut pas être renommée en clientsit_wp : le déplacement est donc un export suivi d’un import, pas un renommage.
Étape par étape
1. Notez ce que vous déplacez. Faites-le avant de changer quoi que ce soit, parce qu’une partie disparaît au retrait du domaine additionnel. Ces commandes se lancent en root.
grep -w clientsite.com /etc/userdomains /etc/localdomains
ls -ld /home/agencyco/public_html/clientsite.com
grep -E "DB_NAME|DB_USER|DB_HOST" /home/agencyco/public_html/clientsite.com/wp-config.php
crontab -l -u agencyco
ls /home/agencyco/mail/clientsite.com /home/agencyco/etc/clientsite.com
Vous devriez voir /etc/userdomains répondre clientsite.com: agencyco, la racine du site appartenir à agencyco agencyco, et le grep sur wp-config.php afficher un nom de base qui commence par agencyco_. Si /etc/localdomains liste aussi le domaine, le courriel est traité sur ce serveur et l’étape 9 vous concerne.
2. Copiez les fichiers pendant que le site est en ligne. Cette première passe est la plus longue et ne coûte aucune interruption. La barre oblique finale du chemin source compte, parce qu’elle copie le contenu du dossier plutôt que le dossier lui-même.
mkdir -p /root/split-clientsite
rsync -aH --info=stats2 /home/agencyco/public_html/clientsite.com/ /root/split-clientsite/files/
Le résumé se termine par une ligne du genre Number of regular files transferred: 24193. Rien n’a changé sur le site en ligne.
3. Exportez la base. Utilisez le nom trouvé à l’étape 1.
mysqldump --single-transaction --routines --triggers --default-character-set=utf8mb4 \
agencyco_wp > /root/split-clientsite/agencyco_wp.sql
tail -1 /root/split-clientsite/agencyco_wp.sql
Un export complet se termine par une ligne qui commence par -- Dump completed on. Si cette ligne manque, l’export a été coupé et vous devez le relancer avant d’aller plus loin.
4. Ouvrez la fenêtre et faites la passe finale. Mettez le site en mode entretien si vous avez une extension pour ça, puis répétez la copie et l’export. La deuxième passe ne transporte que ce qui a changé depuis l’étape 2, donc elle finit vite.
rsync -aH --delete /home/agencyco/public_html/clientsite.com/ /root/split-clientsite/files/
mysqldump --single-transaction --routines --triggers --default-character-set=utf8mb4 \
agencyco_wp > /root/split-clientsite/agencyco_wp.sql
5. Retirez le domaine additionnel du compte d’origine. Connectez-vous au cPanel du compte d’origine, allez dans Domains, trouvez clientsite.com et choisissez Remove Domain. cPanel retire l’hôte virtuel, la zone DNS et l’entrée dans /etc/userdomains. Il laisse les fichiers sur le disque, ce qui vous convient, puisque c’est votre copie dans /root/split-clientsite qui servira. Confirmez que la carte est libérée avant de continuer.
grep -w clientsite.com /etc/userdomains
Ici, le signal de réussite est un résultat vide. Tant que cette commande ne renvoie rien, le domaine est libre.
6. Créez le compte de destination. Choisissez un nom d’utilisateur de huit caractères ou moins, en minuscules, commençant par une lettre. Remplacez le nom du forfait et l’adresse de contact par les vôtres.
whmapi1 createacct username=clientsit domain=clientsite.com \
plan=agency_standard contactemail=owner@clientsite.com
La réponse commence par metadata: result: 1 et reason: Account Creation Ok. Le nouveau compte a maintenant l’utilisateur Linux clientsit, le dossier personnel /home/clientsit, une racine de site vide dans /home/clientsit/public_html et une zone DNS neuve pour le domaine. WHM génère un mot de passe et l’affiche dans la sortie ; conservez-le en lieu sûr et transmettez-le au client par votre canal habituel.
7. Déplacez les fichiers vers la nouvelle racine et corrigez le propriétaire. Le nouveau compte est un autre utilisateur Linux, alors chaque fichier doit changer de propriétaire. C’est la cause numéro un des séparations ratées.
rsync -aH /root/split-clientsite/files/ /home/clientsit/public_html/
chown -R clientsit:clientsit /home/clientsit/public_html
find /home/clientsit/public_html -type d -exec chmod 755 {} +
find /home/clientsit/public_html -type f -exec chmod 644 {} +
chmod 600 /home/clientsit/public_html/wp-config.php
ls -l /home/clientsit/public_html/index.php
La dernière commande doit afficher clientsit clientsit. Si elle affiche encore agencyco, le chown ne s’est pas appliqué au chemin que vous croyez.
8. Créez la base et son utilisateur, puis importez l’export. cPanel ajoute le préfixe du compte tout seul : vous passez le nom court et vous récupérez clientsit_wp.
uapi --user=clientsit Mysql create_database name=wp
uapi --user=clientsit Mysql create_user name=wp password='<new-strong-password>'
uapi --user=clientsit Mysql set_privileges_on_database \
user=clientsit_wp database=clientsit_wp privileges=ALL
mysql clientsit_wp < /root/split-clientsite/agencyco_wp.sql
mysql -e "SELECT COUNT(*) FROM clientsit_wp.wp_posts"
Chaque appel uapi répond result: 1. Le compte final doit correspondre à ce que contenait l’ancienne base. Pour comparer les deux chiffres, lancez mysql -e "SELECT COUNT(*) FROM agencyco_wp.wp_posts". Si votre préfixe de tables n’est pas wp_, lisez-le d’abord dans wp-config.php. Pour le détail du déplacement d’une base entre comptes, voyez migrer une base entre comptes cPanel.
9. Pointez WordPress sur la nouvelle base. Modifiez /home/clientsit/public_html/wp-config.php et changez trois valeurs. Lancez WP-CLI en tant qu’utilisateur du compte plutôt qu’en root, pour que rien de ce qu’il écrit n’appartienne au mauvais utilisateur.
su -s /bin/bash - clientsit -c "cd ~/public_html && \
wp config set DB_NAME clientsit_wp && \
wp config set DB_USER clientsit_wp && \
wp config set DB_PASSWORD '<new-strong-password>' && \
wp db check"
wp db check affiche une ligne par table qui se termine par OK, puis Success: Database checked. C’est WordPress qui lit la nouvelle base avec les nouveaux accès.
10. Déplacez les comptes de courriel du domaine. Sautez cette étape si l’étape 1 n’a montré aucun dossier mail/clientsite.com. Deux dossiers comptent : les messages eux-mêmes, et les définitions de comptes avec leurs empreintes de mot de passe et leurs quotas.
rsync -aH /home/agencyco/mail/clientsite.com/ /home/clientsit/mail/clientsite.com/
rsync -aH /home/agencyco/etc/clientsite.com/ /home/clientsit/etc/clientsite.com/
chown -R clientsit:clientsit /home/clientsit/mail/clientsite.com /home/clientsit/etc/clientsite.com
grep -w clientsite.com /etc/localdomains
uapi --user=clientsit Email list_pops
list_pops doit lister toutes les boîtes qui existaient sur l’ancien compte. Les mots de passe suivent, parce que les empreintes voyagent dans le dossier etc.
11. Recréez les tâches cron. Une table cron appartient à l’utilisateur Linux, alors tout ce que l’ancien compte lançait pour ce site s’est arrêté au déplacement. Lisez l’ancienne table, puis écrivez les lignes concernées dans celle du nouvel utilisateur, avec les chemins corrigés.
crontab -l -u agencyco | grep clientsite.com
crontab -u clientsit -e
crontab -l -u clientsit
Dans l’éditeur, collez les lignes et remplacez chaque /home/agencyco/public_html/clientsite.com par /home/clientsit/public_html. Retirez ensuite ces lignes de l’ancienne table avec crontab -u agencyco -e, pour qu’elles ne se déclenchent pas sur un chemin qui ne contient plus le site.
12. Réémettez le certificat. Le nouveau compte n’a pas encore de certificat pour ce domaine, donc le site répond en HTTP mais échoue en HTTPS. AutoSSL, le service de certificats gratuits de cPanel, règle ça dès que le domaine pointe sur ce serveur et que la nouvelle racine répond.
/usr/local/cpanel/bin/autossl_check --user=clientsit
tail -20 /var/cpanel/logs/autossl/*/*.log
Le journal se termine par une ligne qui nomme les domaines sécurisés. Le certificat s’installe normalement dans la minute ou deux qui suivent la fin de la vérification.
Valider que ça fonctionne
Lancez chacune de ces commandes avant d’annoncer au client que c’est fait.
# Le domaine appartient maintenant au nouveau compte
grep -w clientsite.com /etc/userdomains
# L'hôte virtuel pointe sur la nouvelle racine de site
grep -A3 -w clientsite.com /etc/apache2/conf/httpd.conf | grep DocumentRoot
# Le certificat est actif et couvre le domaine
echo | openssl s_client -connect clientsite.com:443 -servername clientsite.com 2>/dev/null \
| openssl x509 -noout -subject -dates
# WordPress répond en HTTPS avec un 200
curl -sI https://clientsite.com/ | head -1
# WordPress est d'accord sur l'endroit où il vit
su -s /bin/bash - clientsit -c "cd ~/public_html && wp option get siteurl && wp core verify-checksums"
# Plus rien dans le site n'appartient à l'ancien utilisateur
find /home/clientsit -not -user clientsit | head
Vous voulez clientsite.com: clientsit, une racine de site à /home/clientsit/public_html, un certificat dont la date notAfter est dans le futur, HTTP/2 200, un siteurl à https://clientsite.com, Success: WordPress installation verifies against the checksums, et aucune sortie du tout pour le find.
Faites ensuite les vérifications humaines. Connectez-vous à wp-admin, téléversez une petite image, enregistrez un article et envoyez un message d’essai à une des boîtes déplacées. Laissez les anciens fichiers dans /home/agencyco/public_html/clientsite.com pendant une semaine avant de les supprimer.
Dépannage
Le site s’affiche, mais les téléversements et les mises à jour échouent avec une erreur de permission. Des fichiers appartiennent encore à agencyco. Ça arrive quand le deuxième rsync a été lancé après le chown, ou quand un chemin a été mal tapé. Trouvez les retardataires avec find /home/clientsit -not -user clientsit, puis relancez chown -R clientsit:clientsit /home/clientsit/public_html. Vérifiez aussi find /home/clientsit -not -group clientsit, parce que le groupe dérive de la même façon.
WordPress affiche « Erreur lors de la connexion à la base de données ». Le nom de base dans wp-config.php porte encore l’ancien préfixe, ou le nouvel utilisateur n’a jamais reçu ses droits. Voyez ce qui existe avec whmapi1 list_dbs user=clientsit, qui doit montrer clientsit_wp. Testez ensuite les accès directement avec mysql -u clientsit_wp -p clientsit_wp -e "SHOW TABLES" | head. Un échec ici est un problème de droits : relancez l’appel set_privileges_on_database de l’étape 8.
AutoSSL échoue et le journal dit que le domaine n’a pas pu être vérifié. D’habitude, le domaine pointe encore ailleurs, ou le DNS n’a jamais été mis à jour. Regardez ce que le monde voit avec dig +short clientsite.com A et comparez avec l’adresse IP partagée du serveur, donnée par whmapi1 accountsummary user=clientsit. Si la zone est servie par ce serveur, confirmez qu’elle existe avec whmapi1 dumpzone domain=clientsite.com. Si le DNS vit chez un registraire ou chez Cloudflare, corrigez l’enregistrement A là-bas et attendez l’expiration de l’ancien TTL avant de relancer la vérification.
Le courriel rebondit avec « no such user here » après le déplacement. Soit /etc/localdomains a perdu le domaine, soit le dossier etc/clientsite.com n’a pas été copié. Confirmez les deux, puis lancez /scripts/updateuserdomains pour reconstruire les cartes de domaines de cPanel à partir des comptes. Si les boîtes existent mais que l’authentification échoue, le fichier shadow dans etc/clientsite.com n’est pas arrivé avec le bon propriétaire.
Les travaux planifiés s’arrêtent en silence. Personne ne reçoit d’erreur quand une tâche cron disparaît, alors les sauvegardes, les flux et les synchronisations d’inventaire s’éteignent sans signal. Comparez crontab -l -u agencyco avec crontab -l -u clientsit et rendez compte de chaque ligne. Si le site s’appuie sur le planificateur interne de WordPress plutôt que sur cron, vérifiez-le avec wp cron event list sous le nouvel utilisateur, et cherchez les événements dont la prochaine exécution est déjà passée.
Quand ce n’est pas la bonne approche
Si vous déplacez le compte entier, avec tous ses domaines, vers un autre serveur, cette marche à suivre demande plus de travail que nécessaire. Le Transfer Tool de WHM copie tout d’un coup et laisse la source en ligne jusqu’à la bascule.
Si la copie prend des heures, ou si l’entreprise ne peut accepter aucune fenêtre, une séparation directe convient mal. Montez plutôt le nouveau compte sur un sous-domaine temporaire, répliquez la base, et basculez par un changement DNS.
Si les deux sites partagent quoi que ce soit, arrêtez-vous et concevez d’abord. Un dossier de téléversements commun, des liens symboliques entre les racines et des licences liées à un chemin cassent tous quand l’utilisateur Linux change. Un réseau multisite ne se sépare pas du tout de cette façon, parce que ses sites partagent une seule base.
Et si le but est d’empêcher un site bruyant de nuire aux autres, un compte distinct aide pour les quotas et l’isolation des fichiers. Il ne change rien à un processeur partagé ni à un serveur MySQL partagé. Un autre serveur est la réponse honnête là-dessus.
Pour la référence officielle des interfaces et des appels d’API utilisés ici, voyez la documentation cPanel et WHM et la référence des commandes WP-CLI.
Un WordPress qui rapporte vraiment mérite un opérateur — Stack Harbor opère cette pile sous WordPress Entreprise ; réservez une consultation d’infrastructure.