Migrating customers in waves
You do not move customers from your old DirectAdmin, cPanel or Plesk servers to CoreCP in one night, but in waves: a handful of accounts at a time, the same steps every wave, and the next wave only once the previous one runs quietly. This a
Written for: Administrator
You do not move customers from your old DirectAdmin, cPanel or Plesk servers to CoreCP in one night, but in waves: a handful of accounts at a time, the same steps every wave, and the next wave only once the previous one runs quietly. This article is the runbook per wave. It assumes you know DNS and your old panels; it says exactly what you do in CoreCP.
Every wave has five phases: prepare, trial migration, cutover, aftercare and — if it has to — fallback. Only the cutover is noticed by the customer, and it lasts as long as the last copy.
Putting a wave together
Start with your own sites, then small customers, and keep the big web shops for when the routine is second nature. A wave always comes from one source server and goes to one target server.
In the migration screen you choose a wave's accounts with:
- Only these accounts (comma separated) — the wave, by name;
- Leave these accounts behind — what comes later;
- Only accounts of this reseller on the source — a whole reseller in one wave (DirectAdmin and cPanel; Plesk reads the owner from each backup);
- At most this many accounts — for the trial migration: three first.
Preparing, days ahead
- Lower the TTL of every zone in the wave on the source panel to 300 seconds, and wait until the old TTL has run out. If it was 86400, that is a day. This makes both the cutover and the fallback fast.
- Get the target server ready. Install the PHP series the source uses (see PHP and database versions); a website without a matching series is skipped, unless you switch on Serve a missing PHP version on the default instead of skipping. Create the resellers you want to keep, and the packages: reseller packages from cPanel do not come along.
- Give the target server access to the source: an SSH key on the target server whose public half is on the source. In the panel you only enter the path to that key, never the key itself.
The trial migration
Go to Migration → New migration (/migrations/new).
- Choose the Source panel and Remote server, enter
root@old-serveras the Source and choose the Target server. - Choose the Method (or let
autochoose) and click Check the source. It checks that the source has what that method needs: access, the accounts, and where the method writes on the source, the free space. Fix what it names. - Enter the wave's accounts, set At most this many accounts to 3 and click Show the mapping plan (dry run). This writes nothing. Per account you see which websites would be skipped, which mailboxes need a new password, which certificates are about to expire and which A records move along.
- Repeat until the plan is the plan you want, then without the limit for the whole wave.
Per source panel
| DirectAdmin | cPanel / WHM | Plesk | |
|---|---|---|---|
| Methods | native, assemble (read-only), dir | pkgacct (root), user (the account's own login), dir | native (root), dir |
| Copy ahead while the source runs | yes, with assemble | no: an account arrives as one archive | no: a subscription arrives as one export |
| What becomes an account | a DirectAdmin user | a cPanel account | a subscription; you pick it by main domain, the account is named after its system user |
| Freezing on the source | user Suspend | Manage Account Suspension in WHM | subscription Suspend |
| After the cutover | the delta in the same run | the same import once more | the same import once more |
Running an import a second time is safe: what is there stays there, with no duplicate mailboxes or records. That is how you bring in what changed on the source between the trial and the cutover.
With DirectAdmin and assemble you can copy the files and maildirs days ahead while the customer carries on working, and repeat it as often as you like; every pass is a delta. That copying ahead is done in the terminal (--presync, see below). Databases are never part of a copy ahead: a dump hours old misses the orders of those hours. They are dumped fresh at the cutover.
The cutover
- Freeze the wave's accounts on the source (table above). From now on nobody writes on the source.
- Migrate: click Migrate now, or pick the run of your copy ahead under Resume an interrupted run. Follow the progress on the migration screen or under Tasks. If the run is interrupted, start it again with the same choice; it carries on at the account it was on.
- Check every site on the target server before the world sees it: a
hostsline on your own machine, or a request with the rightHostheader straight to the server's address. - Switch DNS. If CoreCP serves the zone, change the delegation at the registrar to your CoreCP nameservers; the zone is already imported and answering. If the customer's DNS stays where it is, change the A and AAAA records there. An SPF record that names the old address was reported by the import but not rewritten: change it per domain yourself.
Records that pointed exactly at the old address already point at the target server after the import; if you do not want that, switch on Leave DNS on the old address.
Aftercare
Open the migration (/migrations/:migration). Every account says OK, WARN or FAIL:
- OK: present and usable, checked on the running server;
- WARN: present, but somebody has to decide something — usually a certificate to request again, a DKIM record under the new selector, or a mailbox whose password could not come along;
- FAIL: it was in the backup and it is not there. That is data loss, and the wave is only done once that row is gone.
Then raise the TTLs back to a normal value, and only once the wave has run well for a while do you clean up the run's working copy.
Fallback
- Before the DNS switch nothing has moved: the source still serves and everything in CoreCP is a copy. Falling back is doing nothing — lift the freeze on the source.
- After the switch you point DNS back at the source and lift the freeze there. Thanks to the low TTL that is everywhere within minutes. Nothing of the source's content was changed: only the methods that write on the source (native, pkgacct, user) make a backup of their own there and remove it again, so it is exactly the server it was.
- What arrived in CoreCP in the meantime — mail, orders — is on the target server. Bring it over before you delete the account there; deleting it (
corectl account remove) is for when you have decided the wave does not go ahead.
To move a customer with as little downtime as possible, without freezing the source, use a live migration. Accounts that are already on CoreCP move between your own servers with Rebalancing accounts across your servers.
From the terminal
On the target server, for a DirectAdmin wave; for cPanel and Plesk it is the same with import cpanel-server or import plesk-server, without --presync:
OLD=root@old-server.example.com
KEY=/root/.ssh/migration
corectl php list
corectl php add 7.4
corectl account add reseller1 --type reseller
corectl import directadmin-server $OLD --identity $KEY --check
corectl import directadmin-server $OLD --identity $KEY --mode assemble --accounts cust1,cust2,cust3 --dry-run --limit 3
corectl import directadmin-server $OLD --identity $KEY --mode assemble --accounts cust1,cust2,cust3 --presync
corectl import directadmin-server --resume <run> --identity $KEY --report /root/wave1.json
corectl import run <run>
corectl ssl issue example.com
corectl mail dkim show example.com
corectl import run remove <run>On the panel, the migrations running now:
corecp-panel tasks list --source migration --activeSee also
- From DirectAdmin, cPanel or Plesk to CoreCP — where to find what.
- Migrating from cPanel and Migrating from Plesk — what comes along per panel and what does not.
- Running a live migration.