Skip to content

External Migrations: from cPanel or DirectAdmin into this server ​

The External migrations page moves hosting accounts from a remote cPanel or DirectAdmin server into this AdminBolt server, and you drive the whole run from the panel. You connect the source once, review the accounts it reports, choose which of them to bring over, and approve the DNS cutover when the run asks for it.

The work itself runs on the source server, not in your browser. Once a run starts it survives a closed tab, a dropped SSH session, and a restart of its own process, so a migration that takes hours does not depend on your workstation staying awake.

Migrating into AdminBolt, not between AdminBolt servers

This page brings a cPanel or DirectAdmin server's accounts into AdminBolt, with their files, databases, and mailboxes. Moving an account from one AdminBolt node to another under a hub is a different feature with a narrower scope, documented in Fleet Accounts. The same source server can also be attached to a hub as a read-only external DNS source, which moves no hosting at all. All of these are compared in Migration: which one do you need?.

This page covers the prerequisites, running a migration step by step, the DNS cutover, recovery after an interruption, and troubleshooting.

Overview ​

URL: /admin/migration/external-migrations - under Migration → External migrations

Migrate accounts from a remote cPanel or DirectAdmin server into this AdminBolt server.

The screen lists your migration runs and starts new ones. Each run has its own page at /admin/migration/external-migrations/<run id>, which is where discovery results, account selection, progress, decisions, and the final report live.

Note: If your sidebar has no Migration row, open the URL above directly. Notification links about a run also take you straight to its run page.

Two ways to migrate from cPanel or DirectAdmin ​

AdminBolt has two paths from the same kind of source server, and they suit different jobs:

External migrations (this page)bolt-migrate on the source
You drive it fromThis panelA terminal on the source server
ScopeThe accounts you selectThe whole server, every account at once
Converts the source in placeNo, the source keeps runningYes, that is one of its two paths
Survives a closed browserYesThe run is tied to your terminal session unless you detach it
Needs a shell on the sourceOnce, to paste a bootstrap command, or not at all if the panel connects over SSH for youYes, throughout

Pick this page when you want a subset of accounts, or when you want the panel to keep the state for you. Pick bolt-migrate when you are converting a server in place or moving everything in one pass.

Before your first external migration ​

  1. Outbound HTTPS from this server to get.adminbolt.com. The panel pins one exact release of the migration runner and fetches it the first time you create a run, then verifies its checksum and keeps the verified copy. If the download fails or does not match the pin, the wizard refuses to create the run rather than start an unverified program as root on a customer's server.
  2. Network from the source to this server. The source needs outbound HTTPS to this panel's port (8443 by default), which is also where it downloads the runner from, and outbound SSH for the data path. On the source itself you need nothing beyond curl and sha256sum.
  3. SSH from this server to the source, but only if you choose the upload bootstrap mode. The one-time command mode needs no inbound access to the source at all.
  4. A second factor on your administrator account. The DNS cutover decision requires it, and the requirement cannot be bypassed. Enable it before you need it, not while a run waits.
  5. Free space on this server for the incoming accounts. Preflight reports the sizes it finds on the source, not what this server has left, so check the target side yourself.
  6. A working backup of the source server. You confirm you have one before a run starts.

Running an external migration ​

1. Connect the source server ​

Open the External tab and enter the source host and SSH port. Add notes if you want the run labelled for a colleague.

2. Approve the host fingerprint ​

The panel reads the source's SSH host key and shows its fingerprint. Compare it with the source before you approve, by running this on the source server:

bash
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Approving pins that key for the whole run. A key that changes mid-run stops the run instead of trusting the new one.

3. Choose how to start the runner ​

Bootstrap methodWhat happensWhen to use it
One-time commandYou paste a command as root on the source. It downloads the runner from this panel over the panel's pinned certificate, verifies the checksum carried in the command, and starts it. Nothing connects inbound to the source.The source is behind a firewall or a bastion, or you would rather not hand over an SSH key.
Upload over SSHThis server connects to the source once, with the private key path or root password you supply, performs the same steps through that session, and drops the connection.You already have SSH access and want fewer manual steps.

Either way the SSH connection is never a control channel. It reads the host key and, in the upload mode, starts the runner. Everything after that flows over HTTPS from the source to this panel.

4. Review discovery ​

The runner enumerates the source and reports the account list with sizes, the capabilities it detected, and preflight results. This step is read-only: nothing on either server has changed yet.

5. Select accounts and start ​

This is where you choose the scope of the run:

ControlWhat it does
Accounts to migrateThe accounts discovery found. Select one, several, or all of them. A run with nothing selected is refused.
Source plan mappingMaps each hosting plan found on the source onto a plan on this server, so migrated accounts land on the limits and features you intend.
Skip file transferProvisions the accounts without copying website files and mail content.
Skip database transferProvisions the accounts and their database users without copying database contents.
I have a working backup of the source serverA required acknowledgement. The run does not start without it.

A failing preflight blocks the start. Fix what it names, then start the run.

6. Watch the run ​

The run page shows overall progress, per-account resource states, and the event log, and it updates while you watch. Closing the browser does not affect the run; reopen the page to pick it back up.

You can Pause, Resume, or Cancel a run. Both pause and cancel take effect at the next safe point, between accounts and between resources, so the page shows cancelling until the runner confirms it has actually stopped. It never reports a stopped run while work is still in flight.

7. Answer the decisions the run asks for ​

The run stops and waits at each gate:

  • Export finished, import into this panel? confirms that the exported packages should be provisioned here.
  • Repoint DNS for the migrated domains to this server? is the cutover decision, covered below. It is always present and always requires an explicit answer.

8. Read the report ​

When the run finishes, the page shows the final report and the cleanup status of the runner, the target, and the panel. A cleanup that did not complete appears as a visible warning with a retry action, not as a silent condition.

DNS and the cutover ​

A migration never changes DNS without your approval, and even then it changes only what lives on a server it controls.

WhatWho changes it
Zones on this AdminBolt server: A, AAAA, SPF, and DKIM recordsThe migration, after you approve the cutover
Zones on the source server, when the source is authoritativeThe migration, if you approve that option
Registrar nameserver delegationYou, by hand
DNS hosted with an external provider such as Cloudflare, registrar DNS, or a third partyYou, by hand. The report lists the exact records

Accounts that failed verification are left out of the DNS change, so a broken account never takes traffic.

Warning: The source keeps serving until DNS propagates, and this version has no delta sync. Treat the source as frozen from the moment the transfer starts: content changed there afterwards is not migrated. Lower your zone TTLs before the migration if you want a fast switch, because propagation takes as long as the old TTL.

If something is interrupted ​

SituationWhat happensWhat you do
You close the browserNothing. The run continuesReopen the run page
The bootstrap SSH session dropsNothing. It only started the runnerNothing
The runner process diesIt is restarted and resumes from its checkpoints, without repeating completed imports, file syncs, or database copiesWatch the run return to running
The source server rebootsThe run stops reporting and shows stalledRun the bootstrap again with the same run id. The working directory and checkpoints are reused
No heartbeat for three minutesThe status flips to stalled and a notification is sent. The runner may still be working behind a broken uplinkCheck the source: systemctl status bolt-migrate-<run id>
One account failsIt is isolated. The other accounts continue, and the failed one is excluded from the DNS cutoverFix the cause, then retry that account
The panel API times out during an importThe runner retries with the same idempotency key and receives the recorded result, rather than provisioning the account twiceNothing

Credentials and cleanup ​

Every credential a run uses is scoped to that run and short-lived. No permanent API key and no agent token is ever placed on the source server.

CredentialWhere it livesWhen it goes away
Enrollment token, valid for minutes and single useThe bootstrap command or a file on the sourceConsumed on first use, and the file is deleted
Run credential, scoped to the run and its endpoints, 12 hour lifetimeRunner memory and the run working directory, mode 0600Revoked on success, failure, cancellation, watchdog expiry, or when the feature is disabled
Transfer key, an SSH key locked to the source address and a forced command, 4 hour lifetimeThe runner working directory, with its public half in this server's authorized_keysRemoved when the run reaches a terminal state, retried by the watchdog, and expired by the agent's own sweep
Per-run database account, granted only on the approved schemasThis server's database, with credentials in a 0600 option fileDropped together with the transfer key

What the transfer key can reach is bounded by this server rather than by good behaviour on the source: file transfer is confined to the staging root and cannot carry ownership, setuid bits, device nodes, or live symlinks across, and the database connection is granted only on the schemas you approved.

To confirm by hand on this server that a finished run left nothing behind:

bash
grep bolt-migration-run /root/.ssh/authorized_keys   # expect no output
ls /var/lib/bolt-agent/migration-targets             # expect an empty directory

Turning the feature off ​

To stop every active run and revoke its credentials:

bash
bolt-cli external-migration-disable

To act on one run only:

bash
bolt-cli external-migration-disable --run=<run id>

Add --force to skip the confirmation prompt.

This revokes every active run credential, removes the transfer credentials through the agent, deletes the run-private SSH material, and marks the runs cancelled. Hosting accounts that were already imported are untouched and keep working as ordinary accounts on this server. To start again afterwards, create a new run.

Troubleshooting ​

SymptomCause and fix
Runner is not availableThis server could not fetch the pinned runner release from get.adminbolt.com, or the download did not match the pinned checksum. The message names which one. Never bypass a checksum mismatch
Could not read the host keyThe source did not answer on SSH. Check the host, the port, and the firewall
Bootstrap fails on curlThe source cannot reach this panel's port, or the panel certificate changed after the command was generated, so the pin no longer matches. Generate a new run
Bootstrap fails on sha256sumWhat the source received is not what this panel serves. Do not bypass it. Check for a proxy between the source and this panel
The run stays in bootstrappingThe runner never enrolled. Check systemctl status bolt-migrate-<run id> on the source, and its outbound HTTPS to this panel
E_CRED_REVOKED in the runner logThe run ended, was cancelled, or the watchdog expired its credential. Start a new run
E_RUN_SCOPE on importThe account is not in the approved selection, or the run is no longer active
E_IDEMPOTENCY_CONFLICTThe same import key was reused with a different payload, which means the source data changed mid-run. Restart the run for that account
Transfer fails although imports succeededThe transfer credential is missing or expired. Check grep bolt-migration-run /root/.ssh/authorized_keys and the agent log, then restart the run for the transfer phase
Status stalled while the source is clearly workingThe uplink from the source to this panel is broken, and the migration continues regardless. Restore outbound HTTPS and the run resumes reporting