Panellicense

Migrate from HestiaCP to cPanel: a step-by-step playbook

A field-tested migration off HestiaCP onto cPanel & WHM — inventory the source, prep the destination, move sites, mail, and DNS without losing customer state.

11 min readUpdated 2026-05-17hestiacp · cpanel · migration · vestacp
schema: HowToschema: FAQPageschema: BreadcrumbList

HestiaCP is the panel small hosts reach for when they want a free, NGINX + Apache stack with built-in mail and DNS — the legitimate successor to VestaCP after that project went quiet in 2019. It works. The migrations we see off Hestia are almost never about a failure of the panel itself: they're about a hosting business that needs reseller accounts, CageFS-level account isolation, a billing-platform-integrated control panel, JetBackup, LiteSpeed Enterprise, or just a brand customers already recognise. None of which Hestia ships.

This guide is the practical, account-by-account playbook for moving an existing HestiaCP server to cPanel & WHM. It assumes a working cPanel destination — if you don't have one yet, start with installing cPanel on a VPS. Budget roughly 20-30 minutes of operator time per account plus 15-30 minutes of customer-visible downtime per DNS cutover. A 30-user Hestia box is a comfortable day of operator work spread across two evenings.

What doesn't translate one-to-one

HestiaCP and cPanel make different defaults that you need to plan around:

HestiaCPcPanel equivalent
NGINX (proxy) + Apache (backend)Apache, or LiteSpeed Enterprise as a paid add-on
Exim + Dovecot + RoundCube + SieveExim + Dovecot + Webmail (Roundcube/Webmail Lite)
NSD as authoritative DNSBIND, PowerDNS, or DNS-only cluster
hestia-php 7.4 – 8.3 multi-PHPEasyApache 4 PHP versions per account
Sites under /home/<user>/web/<domain>/public_html/Sites under /home/<user>/public_html/ per account
Mail in /home/<user>/mail/<domain>/<acct>/ (Maildir)Mail in /home/<user>/mail/<domain>/<acct>/ (Maildir)
v-backup-user tarballs in /backup/pkgacct tarballs in /home/
Single-server, no resellerWHM reseller accounts and ACLs
Built-in fail2ban + iptablescPHulk, ConfigServer Firewall, or Imunify360

The biggest structural difference is that Hestia accounts can hold multiple primary web domains under one Linux user, while cPanel has one primary domain per account and treats additional sites as addon domains under the same /home/<user>. If a Hestia user has three unrelated customer sites bundled together, you have a decision to make at cutover: keep them under one cPanel account (cheaper, less isolated) or split them into one cPanel account each (more billable, properly isolated). Most hosts use the migration as the moment to split.

Step 1 — Inventory the source

SSH into the Hestia server as root and pull a complete picture before touching anything:

# All Hestia users (excludes the admin and system reserved)
v-list-users plain | awk '$1 != "admin" {print $1}'

# Every domain on every user
for u in $(v-list-users plain | awk '{print $1}'); do
  echo "=== $u ==="
  v-list-web-domains $u plain
done

# Mail accounts
for u in $(v-list-users plain | awk '{print $1}'); do
  for d in $(v-list-mail-domains $u plain | awk '{print $1}'); do
    v-list-mail-accounts $u $d plain
  done
done

# Databases and their owners
for u in $(v-list-users plain | awk '{print $1}'); do
  v-list-databases $u plain
done

# DNS zones managed by NSD
v-list-dns-domains admin plain

Capture all of that into a single migration manifest spreadsheet. The columns you want are Hestia user, web domains, database names, mail domains, DNS zones, and a notes column for oddities. The oddities matter — a database with no matching domain usually means a deleted site that never got cleaned up, and a domain pointing at a /web/ directory that doesn't exist is a customer who pointed DNS but never built the site.

Step 2 — Prepare the cPanel destination

On the destination cPanel server:

  1. Match the source's PHP versions through EasyApache 4. Hestia ships PHP 7.4 through 8.3; check which versions the source actually serves with v-list-sys-php. Install the matching versions following adding a PHP version to EasyApache 4. A site running PHP 7.4 on Hestia will not silently work on PHP 8.2.

  2. Match MariaDB / MySQL. Hestia defaults to MariaDB on Debian/Ubuntu and MySQL on RHEL-family. Run mysql --version on the source to confirm, then match it on the cPanel destination — this avoids the JSON-column and authentication-plugin edge cases that bite cross-engine restores.

  3. Pick the web server now, not later. If your customer sites depend on NGINX-level caching configured by Hestia, the cleanest cPanel path is LiteSpeed Enterprise with LSCache for WordPress. Plain cPanel Apache is workable but slower. Install LSWS before the first account move so document roots come up under LiteSpeed from day one.

  4. Decide your DNS topology before the cutover. If the Hestia server was authoritative via NSD, you can either keep its IP serving DNS only post-migration, or rebuild the zones on the new cPanel BIND. Most operators move DNS to a DNS-only cluster on the same migration weekend.

  5. Pre-create resellers and packages. If you're splitting one Hestia user into multiple cPanel accounts, your WHM hosting packages (disk, bandwidth, addon-domain count) need to exist before account creation. Build them under WHM → Packages → Add a Package.

Step 3 — Package each Hestia user

Hestia's v-backup-user creates a tarball that contains the user's web roots, mail maildirs, databases, DNS zones, and cron — everything you need for migration in one file. The tarball is not in pkgacct format, so cPanel's transfer wizard won't ingest it, but the contents extract cleanly with tar and the pieces map directly onto cPanel paths.

On the source for each user:

USER=customerone
v-backup-user $USER
ls -lh /backup/$USER.*.tar | tail -1

The backup lands at /backup/<user>.YYYY-MM-DD_HH-MM-SS.tar. Inside, the structure is:

backup/
├── conf/        # nginx, apache, exim, dovecot per-domain configs
├── web/         # all public_html trees per domain
├── mail/        # Maildir per mail account
├── dns/         # NSD zone files
├── db/          # mysqldump output per database
└── user.conf    # quotas, package, contact email

Move the tarball to the destination via rsync rather than scprsync is resumable on a flaky network and a single user's tarball can be tens of gigabytes on a mail-heavy account:

rsync -P /backup/$USER.*.tar destination:/home/

Step 4 — Restore each user as a cPanel account

On the destination cPanel server, create the new account in WHM under Account Functions → Create a New Account. Pick the cPanel username carefully — Hestia usernames are often longer than cPanel's 16-character limit, so plan a shortened mapping in your migration spreadsheet and notify customers if their FTP username will change.

With the account created, restore the pieces:

CUSER=customer1                     # cPanel username
HUSER=customerone                   # Hestia username
DOMAIN=example.com                  # primary domain on cPanel
TARBALL=/home/${HUSER}.*.tar

mkdir -p /tmp/hestia-restore-$CUSER
tar -xf $TARBALL -C /tmp/hestia-restore-$CUSER

# Web files — primary domain into public_html, addon domains into subfolders
rsync -av /tmp/hestia-restore-$CUSER/web/$DOMAIN/public_html/ \
  /home/$CUSER/public_html/
chown -R $CUSER:$CUSER /home/$CUSER/public_html

# Databases — Hestia prefixes with username, so rename on restore
for sql in /tmp/hestia-restore-$CUSER/db/*.sql; do
  oldname=$(basename $sql .sql)
  newname=$(echo $oldname | sed "s/^${HUSER}_/${CUSER}_/")
  mysql -e "CREATE DATABASE \`$newname\`"
  mysql $newname < $sql
done

# Mail — Maildirs preserve folder structure
for maildomain in /tmp/hestia-restore-$CUSER/mail/*/; do
  d=$(basename $maildomain)
  mkdir -p /home/$CUSER/mail/$d
  rsync -av $maildomain/ /home/$CUSER/mail/$d/
done
chown -R $CUSER:$CUSER /home/$CUSER/mail

The database rename matters: cPanel enforces a <cpaneluser>_<dbname> prefix and rejects operations on databases that don't match it. Restoring under the old Hestia prefix leaves the database visible only over SSH, never in cPanel's MySQL UI.

After the file restore, update any WordPress wp-config.php, Joomla configuration.php, and Drupal settings.php to use the new database name and the new MySQL password cPanel generated:

sed -i "s/${HUSER}_/${CUSER}_/g" /home/$CUSER/public_html/wp-config.php
sed -i "s/DB_PASSWORD',.*'/DB_PASSWORD', 'newpass-here'/" /home/$CUSER/public_html/wp-config.php

The site-config edit is the step people skip and then waste an hour debugging "internal server error" on a freshly migrated site.

Step 5 — Recreate mail accounts and DKIM

The Maildir data is already in place, but cPanel needs the mailbox to exist in its own account database before IMAP will serve it. For each mail account on the source:

  1. Create the account in cPanel → Email Accounts with the same local part.
  2. Either set the same password the customer was using (if you captured it during a pre-migration prompt) or force a reset and notify them.
  3. Re-publish DKIM. Hestia generates DKIM keys per domain under /etc/exim4/domains/<domain>/dkim.pem; those keys are not portable to cPanel. Generate fresh DKIM in cPanel → Email Deliverability for each domain, and follow cPanel email deliverability with SPF, DKIM, and DMARC to get the records right at cutover.

Reusing the old DKIM selector tanks deliverability for a week while inbox providers learn the new key. Publish the new selector ahead of the DNS cutover so the records are warm when mail starts flowing.

Step 6 — DNS cutover

Drop public DNS TTLs to 300 seconds at least 24 hours before the cutover. On the day:

  1. Verify the destination cPanel site responds correctly over the new IP: curl -I --resolve example.com:443:NEW.IP.HERE https://example.com/. A 200 or expected redirect means the document root and SSL are wired up.
  2. Update A and AAAA records at the registrar or external DNS to point at the new server.
  3. If you're moving DNS hosting too, change the NS records last and only after the authoritative zones serve correctly from the new nameservers.
  4. Trigger AutoSSL on the new account from WHM → SSL/TLS → Manage AutoSSL → Check "username" Now. If issuance fails, work through the WHM AutoSSL failures decision tree — most post-migration AutoSSL failures are stale CAA records published by Hestia's Let's Encrypt integration.

Step 7 — Decommission carefully

Leave the Hestia server up for at least 7 days post-cutover, serving the same vhosts so direct-IP traffic and stale resolvers continue to land somewhere. Pull mail from the old IMAP store once per day during the grace window — IMAP clients can fail over slowly, and any mail delivered to the old Maildir in that window is invisible to the customer until you copy it across.

After the grace period, snapshot the source, archive it to cold storage for 90 days (enough to cover a customer "I lost a file" ticket), and destroy the instance. Reusing the Hestia OS image to spin up new servers is fine — Hestia itself isn't the security liability that drives most CyberPanel migrations.

FAQ

Is there a one-shot tool to migrate HestiaCP to cPanel?+
No. Hestia's v-backup-user produces a tarball, not a pkgacct-compatible archive, and cPanel's transfer wizard only ingests from cPanel, Plesk, DirectAdmin, and a couple of legacy panels. The migration is account-by-account: package the user on Hestia, create the cPanel account, extract files and Maildirs, restore renamed databases, recreate mail accounts.
Can I keep one Hestia user's multiple sites under one cPanel account?+
Yes — Hestia's bundled web domains map to cPanel's primary domain plus addon domains under the same /home/<user>. Most hosts use the migration as the moment to split them into separate cPanel accounts instead, since proper isolation and per-customer billing are usually why you're moving in the first place.
Will customer mailbox passwords survive the migration?+
No. Hestia stores mailbox credentials salted in /etc/exim4/domains/<domain>/passwd in a format cPanel cannot import. Either set the same password on the new cPanel mailbox if you know it, or force a customer-side reset at cutover and notify them in advance.
What happens to DKIM keys when I move from HestiaCP to cPanel?+
Hestia's per-domain DKIM keys under /etc/exim4/domains/<domain>/dkim.pem are not portable. Generate fresh DKIM in cPanel's Email Deliverability tool per domain, publish the new selector ahead of the DNS cutover, and let inbox providers re-key cleanly rather than trying to reuse the old key.
How long does a HestiaCP to cPanel migration take?+
Plan on 20-30 minutes of operator time per account plus 15-30 minutes of customer-visible downtime per DNS cutover. A 30-user Hestia box is one full operator-day spread across two evenings if you stagger cutovers across the customer base.
Should I migrate to Plesk instead of cPanel?+
The playbook is structurally identical for Plesk — the differences are in the account creation step (Plesk subscriptions instead of cPanel accounts) and the DNS templates. If you're still undecided on the destination panel, read [cPanel vs Plesk in 2026](/kb/cpanel-vs-plesk-2026) before you start the migration.

Next steps

Switch in an afternoon

Switch from your current reseller — free.

We migrate active cPanel, Plesk, LiteSpeed and CloudLinux licenses from any reseller. We prorate the first month so you never pay twice, and your customers see zero downtime during the swap.