← Tutorials
CorePanel intermediate · ~30 min ·

Migrate cPanel accounts to CorePanel over SSH, straight from the WHM server

With root on the cPanel server, CorePanel lists its accounts, packages the ones you pick, copies them across and imports them, one after another, with passwords, mail, databases and DNS. No archive to carry, nothing changed on the source.

When you run the cPanel server yourself, the quickest way to move accounts off it is to let CorePanel fetch them. You give it the server’s address and root’s password; it lists every account, you tick the ones to move, and it does the rest on its own, one account at a time: pkgacct on the source, the copy, the import, the report. You can close the browser while it works.

The source server is only read. Its accounts keep serving until you move their DNS, so you can migrate a few sites a night and leave the rest where they are.

The examples move the account shop, with the domain example.org: WordPress on PHP 8.1 with its database shop_wp, and the mailbox info@example.org. The cPanel server is cpanel.example.net (198.51.100.5). The CorePanel server comes from Install CorePanel and host your first website: 203.0.113.10, with ns1.example.com and ns2.example.com as its nameservers.

Let CorePanel log in to the cPanel server

CorePanel connects to the cPanel server over SSH as root, with a password. Many cPanel servers only accept keys for root, and that is the better setting, so open password login for root to the CorePanel server’s address only, for the time the migration takes. On the cPanel server, add this at the end of /etc/ssh/sshd_config:

Terminal window
cat >> /etc/ssh/sshd_config <<'EOF'
# CorePanel migration — remove when done
Match Address 203.0.113.10
PasswordAuthentication yes
PermitRootLogin yes
EOF
sshd -t
systemctl reload sshd

It has to go at the end: everything after a Match line belongs to it. sshd -t checks the file before the reload. If the server also runs cPHulk or CSF, allow 203.0.113.10 there too, so a mistyped password does not get the CorePanel server blocked.

The password is used for the connection only: CorePanel does not store it.

Connect and pick the accounts

In CorePanel, open Backup & Transfers → Transfers. Enter the cPanel server’s host name or IP address, the SSH port (22), root and its password:

The Transfers tab with two ways to import from cPanel — cPanel/WHM with root, and cPanel with the account&#x27;s login — and the four steps Connect, Select account, Options and Confirm, on the Connect step that asks for the source server and its root credentials.

CorePanel lists every account on the server, with its domain, plan and disk usage, and shows the server’s SSH host-key fingerprint. Compare the fingerprint with the server’s own before going on. On the cPanel server, this prints it:

Terminal window
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Tick shop. To move several accounts, tick them all, or filter the list and use Select all; suspended accounts are marked, and come over suspended.

The Select account step: the source server&#x27;s name, cPanel version and SSH host-key fingerprint, a search box and Select all, and a list of accounts with their domain, plan and disk usage, one of them marked Suspended, three of them ticked.

Choose the options

The Options step: a target hosting package selector, a Preserve UID / GID switch, and a Point DNS to this server switch that repoints the account&#x27;s A records on the source server once its import finishes.

  • Target hosting package. Leave it empty and each account goes to the CorePanel package with the same name as its cPanel plan, if there is one. Either way the account keeps the limits cPanel recorded for it.
  • Preserve UID / GID. Switch it on. The files keep their numeric owners, which matters for anything that recorded them.
  • Point DNS to this server. When an account finishes, CorePanel logs in to the cPanel server again and changes, in its DNS zones, the A records that pointed at the old IP to this server’s. That moves visitors over within minutes when the cPanel server is still the domain’s nameserver and you are not ready to change nameservers. In this tutorial the domain moves to CorePanel’s own nameservers, so leave it off.
  • If the account or domain already exists. Keep Abort: nothing is overwritten.

Review the summary and click Start.

Watch it work

Live progress of one account at 62%: a phase tracker Connect, Transfer, Restore, Done; a Transfer card with the connection, pkgacct and the downloaded archive; a Restore card counting created, reset, deferred, dropped and failed resources with a Copy the home directory bar; and the list of resources below.

For each account, CorePanel runs pkgacct on the cPanel server, copies the archive across, creates the account and restores into it, and writes a report. Accounts go one at a time, so the cPanel server never packages two at once. The job runs on the CorePanel server: close the page and pick it up later from Recent imports. A 100 MB account takes under a minute.

When it is done, the account is here:

Terminal window
corepanel account list
corepanel wp list shop
corepanel mail list example.org
| 2 | example.org | shop | 1 | 1/∞ | 1/∞ | 0/∞ | | active |
ID STATUS VERSION SITE URL PATH
1 ok 7.1.2 https://example.org /home/shop/public_html
info@example.org active quota=1024 MB

The report says what came over, resource by resource:

  • the account, its password and its FTP logins, with their passwords;
  • the site, at the same path as on cPanel, /home/shop/public_html;
  • the database shop_wp, with its user and that user’s password, so wp-config.php works unchanged;
  • the mailbox, with its messages and its password;
  • the DNS zone, with its custom records, and every record that pointed at 198.51.100.5 rewritten to 203.0.113.10;
  • the WordPress site, now in the WordPress list.

It also has two warnings. The site ran PHP 8.1 and runs on 8.4 here, the newest version of the same major release, because 8.1 is not installed on this server. And cPanel’s default plan has no package of that name here, so the account is not attached to one.

Test before the DNS moves

Visitors still reach the cPanel server. Ask the new one directly:

Terminal window
curl -sk --resolve example.org:443:127.0.0.1 https://example.org/ | grep -o '<title>[^<]*</title>'
curl -sk --resolve mail.example.org:993:127.0.0.1 --url 'imaps://mail.example.org/INBOX' --user 'info@example.org:Info-Shop-2026!' -X 'STATUS INBOX (MESSAGES)'
<title>Example Shop</title>
* STATUS INBOX (MESSAGES 1)

The page came from the imported database on PHP 8.4, and the mailbox opened with its cPanel password. -k skips the certificate check: the free certificate is only issued once the domain points here. To browse the site, add 203.0.113.10 example.org www.example.org to the hosts file of your own computer and remove it when you are done.

Switch the DNS

At the registrar, change the nameservers of example.org to ns1.example.com and ns2.example.com. The zone on CorePanel is already complete.

Terminal window
dig +short NS example.org
ns1.example.com.
ns2.example.com.

CorePanel checks every 30 minutes whether a domain waiting for its certificate has been delegated, then orders a wildcard for example.org and *.example.org:

Terminal window
timeout 2400 bash -c 'until echo | openssl s_client -connect example.org:443 -servername example.org 2>/dev/null | openssl x509 -noout -ext subjectAltName 2>/dev/null | grep -q "\*.example.org"; do sleep 10; done'
curl -fsS -o /dev/null -w '%{http_code}\n' https://example.org/
200

Mail sent while senders still had the old answer cached lands on the cPanel server. Keep the account there for a few days, then move any late messages across from a mail app connected to both mailboxes.

Close the door you opened

When the last account you are moving has landed, remove the Match block from /etc/ssh/sshd_config on the cPanel server, then sshd -t and systemctl reload sshd. Root is back to keys only. A week after the switch, remove the migrated accounts from cPanel with /scripts/removeacct <user>.

What you have now

On cPanelOn CorePanel
Sitepublic_html, PHP 8.1Same path, PHP 8.4, under WordPress
Databaseshop_wpshop_wp, same user and password
Mailinfo@example.orgSame mailbox, same password, its messages
DNSZone on the cPanel serverZone on CorePanel, records kept, IPs rewritten
Source serverServing, untouched—

The other accounts are still on cPanel, waiting for the next batch. When the last one is gone, or if you would rather convert the whole server at once, in place and with a way back, see Transform. No root on a cPanel server, only an account’s login? Move a website off shared cPanel hosting.