deplaneDocs Dashboard

Moving from cPanel

Move a WordPress site from a cPanel host to Deplane with one command: deplane import cpanel reads the cPanel account, shows what moves and what stays, then copies the site's files, database and users into a new WordPress app. You test the copy on its own address while the old host keeps serving your domain; when it works, you run the command once more with --cutover and change DNS. Email stays at your host.

The command runs on your own computer with a cPanel API token that never leaves it. It only reads cPanel, apart from writing one backup file into your home directory. The command and its flags are in the CLI reference, and every error has a fix in Troubleshooting and error codes. There is no cPanel import in the dashboard yet: use the CLI.

Before you start

  1. Install the Deplane CLI and run deplane login.
  2. Be on a plan with MySQL (Hobby or larger): a WordPress site needs a small app, a medium MySQL and a 5 GB disk. Free has no MySQL, and the report says so.
  3. Find your cPanel server's name: the address you open cPanel at, such as https://server1.host.example:2083. Use that name for --host, not your own domain. Your cPanel username goes in --user.

The API token

Create a token in cPanel: Security, Manage API Tokens, Create. Name it deplane-import and give it an expiry date (tomorrow is enough). A token works when your account has two-factor authentication, and you can revoke it in the same screen when you are done. Deplane takes only a token, never your cPanel password.

Give the token to Deplane in one of three ways, never as a flag:

A token piped on stdin wins over CPANEL_API_TOKEN. The CLI says which one it used, never the token itself. It sends the token only to your cPanel server (https://HOST:2083). It is never written to disk, never printed, left out of --debug, and never sent to Deplane or to your app.

Check first

--check reads the account and prints the report without changing anything:

$ deplane import cpanel --host server1.host.example --user shop --check < token.txt
example.com (cPanel shop@server1.host.example, WordPress 6.8.1, PHP 8.1) → Deplane app example-com

Site
  ✓ example.com, document root /home/shop/public_html on server1.host.example → Deplane app example-com.
  ✓ Left out: the files of other.example, which live inside this folder (each site is imported on its own, with --site).

WordPress
  ✓ WordPress 6.8.1, wp-config.php in the document root.
  ✓ Table prefix wpx7_, kept (WORDPRESS_TABLE_PREFIX).
  ✓ PHP 8.1 on cPanel → PHP 8.4 on Deplane.
  ⚠ Other settings in wp-config.php are not copied: MAILGUN_API_KEY. ...

Database
  ✓ shop_wp (84 MB on cPanel) → a new MySQL example-com-mysql (MySQL 8.4, medium), from the backup's dump. ...

Files
  ✓ cPanel writes a full account backup into your home directory, and the CLI downloads it to this computer. ...

Email and DNS
  ⚠ Email for example.com stays at your host (3 mailbox(es), MX mail.example.com (0)). ...

Plan
  ✓ Fits your plan: a small app, a medium MySQL and a 5 GB disk (the WordPress template).

Without --site, the report is about the account's main domain; pass --site example.org for an addon domain or subdomain. The app is named after the domain (example.com becomes example-com) unless you pass --name. Values from wp-config.php, such as the database password, are never shown or sent anywhere.

What the import does

Without --check, after you confirm (--yes skips the question):

  1. Backup. cPanel writes a full account backup (backup-…_USER.tar.gz) into your home directory, and the CLI downloads it to your computer. It keeps only the site's document root and its database dump, in a private temporary folder that is deleted at the end. The full backup includes your email, so it can be larger than the site.
  2. Sizes. The site's files and dump are measured here, before anything is created on Deplane: up to 4.5 GB of files (the app's disk is 5 GB, and the rest is room for new uploads) and up to 5 GB of database.
  3. The app. It is created from the WordPress template: the app, its MySQL and its disk, as deplane launch --template wordpress would.
  4. Files and database. The CLI turns on the app's one-time import receiver, replaces the fresh WordPress files with your site's (WordPress core, themes, plugins and uploads), empties the database, loads your dump, and turns the receiver off. Meanwhile the app shows a "being moved" page to everyone, so no visitor sees a half-copied site. Your wp-config.php is not copied: Deplane's own reads the database settings Deplane manages, and your table prefix is kept.
  5. Test address. Your site's addresses in the database (https://example.com, its http and www forms) are rewritten to the app's own address, such as https://example-com.deplane.app, so you can test every page there. The rewrite understands PHP's serialized values (widgets, theme options, page builders), as wp search-replace does.

Then it prints the test address and the steps left. Sign in at /wp-admin with your usual WordPress user and password: the users come with the database. Everyone is signed out once, because Deplane uses new security keys.

The copy on the test address is public, like your site. If something went wrong, run the same command again: it replaces the files and database of the app an earlier import made of the same site, without creating anything new. It backs up the app's disk and MySQL first and prints the commands to restore them. If a run stops half-way, the app keeps showing the "being moved" page until a run finishes.

WordPress's web installer (/wp-admin/install.php) is always blocked on Deplane: Deplane installs WordPress itself, so nobody can take over a site whose database is empty.

What the backup fix-ups change

PHP and WordPress versions

Deplane runs WordPress on PHP 8.4. Your site keeps the WordPress version it has; update it from the dashboard afterwards. The report warns when your site runs PHP older than 8.1 (plugins and themes that use removed functions may break), and when WordPress is older than 6.7, the first version that supports PHP 8.4. Update WordPress, themes and plugins on the old host first if you can, and test every page on the test address.

What is refused

These stop the import before anything is created, with a ✗ line:

Email stays at your host

Deplane does not host email. Your mailboxes, the MX records and the mail server stay at your cPanel host; only the website moves. The report shows the domain's mailboxes and MX records.

Watch for one trap: if the MX record names your domain itself (example.com), or mail.example.com is a CNAME to it, then pointing the domain at Deplane moves mail delivery too, and email stops arriving. Before the cutover, give mail.example.com its own A record to your cPanel server's IP address (the report shows it) and point the MX record at mail.example.com. Keep the SPF, DKIM and DMARC TXT records as they are.

The cutover

When the test copy works:

  1. A day before, lower the TTL of your domain's A record and the www record to 300 seconds at your DNS provider.
  2. Stop editing the old site (or put it in maintenance mode), so nothing is lost.
  3. Run the same command with --cutover:

``sh $ deplane import cpanel --host server1.host.example --user shop --cutover --yes < token.txt ``

It copies the files and database again, this time without the address rewrite (only http:// links become https://), sets the site's address to your domain, and adds example.com and www.example.com to the app. It prints the DNS records for both, as deplane domains add does. Anything changed on the test copy is replaced.

  1. At your DNS provider, set the TXT records, then the A record of example.com and the CNAME of www. Remove any AAAA record of the domain. Keep the MX records, mail, and the SPF, DKIM and DMARC records. See Custom domains.
  2. Deplane connects the domain and gets its certificate within minutes of DNS pointing at it. Until then, the app's own address redirects to your domain, which still reaches the old host.

After the cutover

The app is now your live site. Running the import again, or --cutover again, would replace it with the cPanel copy and lose everything changed on Deplane since: orders, posts, comments, users. So the command asks you to type the domain first, and --yes does not skip that; in a script, pass --replace-live if you really mean it. An app with a custom domain attached counts as live too, cutover or not. Either way it backs up the disk and the MySQL first, for this run, and prints the restore commands; if a backup already ran in the last hour, it stops without deleting anything and asks you to run it again when the next backup is allowed.

If an import stopped half-way

The app keeps showing the "being moved" page until an import finishes, also after a restart, so nobody sees a half-copied site. Run the same command again: it says it found the page from an earlier run, replaces the files and database, and ends it. To go back instead, restore the disk and MySQL backups the earlier run printed.

Afterwards

If cPanel does not let the token download

Some hosts let only a signed-in browser download files. Then the command stops after the backup is made, with cpanel_download_refused, and nothing is created on Deplane. Download the backup yourself and pass it with --backup:

$ deplane import cpanel --host server1.host.example --user shop --backup ~/Downloads/backup-10.31.2026_12-00-00_shop.tar.gz --yes < token.txt

--backup takes a full account backup (cPanel, Backup, "Download a Full Account Backup"), or a home directory backup with the database's own backup in --db-dump (shop_wp.sql.gz from the same screen). The token is still needed: the CLI reads the site's settings from cPanel.

Limits

LimitValue
Sites per command1 (run it once per domain, with --site)
Site files4.5 GB, one file at most 4.5 GB
Database5 GB as cPanel reports it; 8 GB of SQL; one statement 32 MB
PHP8.4
Multisite, WordPress in a subfolder, sites without WordPressNot imported yet
DashboardNot yet: CLI only
Space on your computerAbout the site's files plus twice the database, in the temporary folder (TMPDIR)

This page is also available as Markdown. AI agents can start at /llms.txt.