@@PRODUCT@@

Running a live migration

Moving a customer off a running server onto CoreCP without the site being down for hours. This is the guided version: one wizard that puts the steps in the order somebody actually does them, may run for days, and survives you closing the la

Written for: Administrator

Moving a customer off a running server onto CoreCP without the site being down for hours. This is the guided version: one wizard that puts the steps in the order somebody actually does them, may run for days, and survives you closing the laptop. If all you want is to read in a backup file, read "Migrating from cPanel" instead.

The wizard is in the panel under Migration → Live migrations, and the same steps are commands on the node. It is one record: what you start in the browser you can finish on the server, and the other way round.

The nine phases

PhaseWhat happens
Connectcredentials per service (SSH, FTP, MySQL, IMAP), and a test that says what does and does not work
Discoverthe source is read: sites, databases, mailboxes, zones
Planwhat goes where, plus a dry run of the real transfer commands
Approvea person approves the plan; only then may data move
Syncthe first pass, and as many deltas as the week needs
VerifyHTTP comparison, mailbox counts, row counts, zone completeness
Ready for cutoverthe green signal: plan approved and every check green
Cutoveryou (or the customer) move the nameservers or A records — CoreCP does not
Finalisefinal delta under a short freeze, certificates, and advice about the old machine

The phase is derived from the record and stored nowhere. If a colleague runs a delta from the command line while you are watching the browser, there is no second copy of "where are we" to go stale.

Getting started

In the panel: Migration → Live migrations → New migration. You fill in the details per service — one tab per service — and press test. What does not work may be missing: without SSH the wizard runs in "degraded" mode over FTP, IMAP and MySQL-over-TCP, and the report says which route it used.

From the node that is:

ssh root@stck1.corecp.dev
corectl migrate source add web1 --keep-for-delta --retain-days 30 < creds.json
corectl migrate source test lm-1786… --install-key

--install-key sets up a key pair that exists for this migration only; that is the preferred path over passing a password around.

If the old server does not allow password logins, that step cannot work — and it is not a wrong password. SSH answers such an attempt with "Permission denied (publickey)", which reads as if the password were wrong when it was never offered at all. Since 0.19.1 CoreCP says so, and hands you the key line you need:

root@stck1:~# corectl migrate discover lm-1786…
corectl: installing this migration's key on olduser@old.example.com failed:
exit status 255 — Permission denied (publickey).

The source offered public-key authentication only, so the password was never
tried … Install this migration's key on the source by hand, in the account's
~/.ssh/authorized_keys, and run this again:

  ssh-ed25519 AAAAC3Nza… corecp-migration lm-1786…

Put that one line into ~/.ssh/authorized_keys of the account on the old server by hand and run the command again. Everything after it uses the key.

Discover, plan, approve

corectl migrate discover lm-1786…   # read the source
corectl migrate plan     lm-1786…   # plan + dry run
corectl migrate approve  lm-1786…   # a person approves

The dry run is not an estimate: it is the transfer engines themselves with their own --dry-run. What you read is what will happen. Approval is a step of its own because it is the one place where somebody can say "that is wrong" before any data moves.

Sync

corectl migrate sync lm-1786… --pass initial
corectl migrate sync lm-1786… --pass delta     # as often as you like

A pass runs the plan's items in parallel, throttled — three at a time — because the source is a live server still serving its own customers. Each item is its own step with its own log, shown in the panel in a slide-over.

Everything is resumable. A step left "running" by a reboot is honestly labelled partial — interrupted, run the pass again to resume after six hours.

Verify, and the green signal

corectl migrate checklist lm-1786…
corectl migrate status    lm-1786…
[corecp] live migration lm-1786… → web1 (ready)
  discovery:   ssh, directadmin layout — 2 site(s), 1 database(s), 1 mailbox(es), 1 zone(s)
  plan:        5 item(s), approved 2026-08-10 11:02 by admin@corecp.dev
  READY FOR CUTOVER — every check is green.

"Ready for cutover" means exactly two things at once: the plan is approved and every check is green. Every new pass drops the checklist, because a green tick that predates the data it is ticking is the one failure this wizard cannot have. A checklist with no checks in it is not green either.

Cutover and finalise

Move the nameservers or the A records. CoreCP does not do this for you: it is the one step whose consequences the customer carries.

corectl migrate cutover  lm-1786…   # confirm DNS has been switched
corectl migrate finalise lm-1786…   # final delta, certificates, advice

The final round does files with a quick pass, mail with a flag resync, and the databases again under a short freeze. Certificates are requested after that, HTTP-01 per name: before the switch the challenge is still answered by the old server. A name that has not propagated is a warning with the retry command, not a failed migration.

The advice about the old machine is advice. CoreCP does not switch off a server it does not own.

Cleaning up

corectl migrate source forget lm-1786…

This is not optional housekeeping: until it runs, this node holds a working login to a machine the customer is about to stop paying for. corectl migrate expire does it by itself if nobody remembers, and migrate source show says how long that still is.

What the migration does with passwords

Two sides, and they are not the same.

The old server. You give a login for it, and that is a real one: it is kept encrypted for as long as the migration runs and disappears with migrate source forget, or by itself with migrate expire. It never reaches a log or an error message — CoreCP filters it out before anything is written down.

The new server. There, CoreCP does not have your mailbox password: it is only ever stored hashed. So for the copy the migration mints a temporary key that opens only that one mailbox, and revokes it again when the pass ends. That key is not a password: you cannot type it into a mail client, and it opens no other mailbox. If you happen to be in webmail at that moment you notice nothing of the clean-up — your own session stays.

Who sees the migration, and what happens when the server moves

A migration belongs to the server it runs into, not to the group that server happened to be in when you started. Move the machine to another server group and its migrations move with it: the new group's administrator sees them, the old one no longer does.

It also means you can safely tidy away the old, emptied group. The migration records stay — they belong to the machine, and the machine is still there.

corectl migrate status lm-1786…      # the migration itself, on the node
lm-1786… · sync · 3 of 7 passes · source web1.old-host.example

If a migration you expect is missing from the overview, check which group the destination server is in first. Under Servers, the group is on the machine's detail page.

See also

  • Migrating from cPanel
  • Where a website is served

Moving an address is something else

This page is about moving a customer from another server. If the IP address of your own server is moving — your provider delivers a new block, or you go to another data centre — that is a different wizard, with a period in which your sites answer on both addresses. See Replacing an IP address.

Moving a node's own storage

Besides customer migrations there is one move that is about the server itself: the records CoreCP keeps for its own use — the mail list and the zone data — move out of the customers' database engine into a store that belongs to the node. Do it node by node, and only throw the previous copy away after you have watched a node for a while.

Look at what would move first; this changes nothing:

corectl node store migrate --dry-run

Then run the move. It provisions the store, copies every table, counts on the far side what arrived, and has the services read from it:

corectl node store migrate
corectl node store status

If anything is not as expected, the way back is one command — the old copy is still there:

corectl node store rollback

Only once the node has run well for a while do you drop that old copy. After that the move cannot be undone without a restore:

corectl node store remove-legacy --confirm