Panellicense

Migrate from CentOS Web Panel (CWP) to cPanel: full playbook

A field-tested migration off CentOS Web Panel onto cPanel & WHM — inventory the source, convert Postfix mail layouts, restore databases without prefix conflicts, cut DNS without breaking AutoSSL.

12 min readUpdated 2026-05-21cwp · centos-web-panel · cpanel · migration
schema: HowToschema: FAQPageschema: BreadcrumbList

CentOS Web Panel — now branded Control Web Panel since the CentOS rebrand, but everyone still types cwp into the URL bar — is the free panel that most small RHEL-family hosts land on after outgrowing a manual LAMP build. It runs Apache (with optional NGINX reverse proxy or Varnish), Postfix + Dovecot for mail, and BIND for DNS, all wrapped in a PHP UI that listens on ports 2030/2031 (free) and 2086/2087 (Pro). It's free, it works, and the moment you need reseller accounts that you can actually bill, CageFS-grade tenant isolation, JetBackup-quality backup, or a panel your customers have heard of, you start planning the move.

This guide is the practical, account-by-account playbook for moving an existing CWP 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 25-35 minutes of operator time per account plus 15-30 minutes of customer-visible downtime per DNS cutover. A 25-user CWP box is a comfortable day of operator work split across two evenings, including the mail format conversion that's the slowest part.

What doesn't translate one-to-one

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

CWPcPanel equivalent
Apache + optional NGINX/Varnish frontApache, or LiteSpeed Enterprise as a paid add-on
Postfix + Dovecot + RoundcubeExim + Dovecot + Webmail (Roundcube/Webmail Lite)
BIND, free-form zone filesBIND or PowerDNS, or a DNS-only cluster
cwpsrv-php 7.4 – 8.3 multi-PHPEasyApache 4 PHP versions per account
Sites at /home/<user>/public_html/Sites at /home/<user>/public_html/
Mail at /home/vmail/<domain>/<acct>/Maildir/Mail at /home/<user>/mail/<domain>/<acct>/
Databases with no enforced prefixDatabases enforced to <cpaneluser>_<dbname>
CWP backup .tar.gz under /home/cwp-backup/pkgacct tarballs under /home/
Built-in CSF + ModSecuritycPHulk + ConfigServer Firewall or Imunify360
Single-server, no real reseller tier in FreeWHM resellers with ACLs and packages

The two structural traps to plan for are mail layout and database naming. CWP runs Postfix with vhost-style mail storage under /home/vmail/, a directory owned by the vmail user and unrelated to the customer's Linux account. cPanel runs Exim with mail under each customer's own /home/<user>/mail/ tree. The Maildir contents themselves are byte-compatible — Dovecot wrote them the same way on both panels — but the path move and ownership rewrite are mandatory or IMAP won't serve a single folder.

Database naming is the second trap. CWP lets a user create wp_main, crm, and shop_db_2023 with no prefix. cPanel enforces <cpaneluser>_<dbname> and refuses to manage databases that don't match. Plan a rename map in your migration manifest before you restore anything.

Step 1 — Inventory the source

SSH into the CWP server as root and pull a complete picture before touching anything. CWP keeps its account metadata in MySQL in the root_cwp database, which is the fastest place to list everything:

# All CWP accounts (excludes the cwp admin)
mysql -e "SELECT username, domain, package, owner, status FROM root_cwp.user;"

# Addon and subdomains per primary account
mysql -e "SELECT username, parked, type FROM root_cwp.domains;"

# Mail accounts (Postfix virtual mailbox table)
mysql -e "SELECT id, email, quota FROM root_cwp.email_accounts;"

# Databases and their owners
mysql -e "SELECT username, db_name FROM root_cwp.mysql_db;"

# DNS zones managed by BIND
ls /var/named/*.db | awk -F'/' '{print $4}' | sed 's/\.db$//'

Dump the four queries into a spreadsheet and add columns for the target cPanel username (remember the 16-character limit), the renamed database name, and a notes column for oddities. The notes are where you catch the customer who has 12 GB of mail in a single Maildir and the one whose public_html is actually a symlink to /var/www/.

Step 2 — Prepare the cPanel destination

On the destination cPanel server:

  1. Match the source's PHP versions through EasyApache 4. CWP exposes PHP 7.4 through 8.3 via cwpsrv-php; check which versions the source actually serves in CWP → PHP Selector → PHP Settings per User, then install matching versions per the EasyApache 4 add-PHP-version guide. A site running on PHP 7.4 with deprecated extensions will not silently work on PHP 8.2.

  2. Match MariaDB / MySQL. CWP defaults to MariaDB 10.5 or 10.11 depending on install age. Run mysql --version on the source, then match it on the destination — this avoids the JSON-column and mysql_native_password edge cases that bite cross-version restores.

  3. Pick the web server and security stack before the first cutover. If the CWP server was running NGINX in front of Apache for cache, the cleanest cPanel equivalent is LiteSpeed Enterprise with LSCache for WordPress. For the security replacement, install Imunify360 before the first account move so ModSecurity rules and proactive defence are live from day one.

  4. Decide your DNS topology before the cutover. CWP runs BIND with zone files under /var/named/, which copy cleanly to cPanel's BIND. Most operators take the migration weekend to move DNS to a DNS-only cluster and stop running authoritative DNS on the same box as the web stack.

  5. Pre-create resellers and packages. Build your WHM hosting packages (disk, bandwidth, addon-domain count, feature lists) under WHM → Packages → Add a Package before you start creating accounts. CWP's free tier doesn't have a real reseller layer, so this is often the first time those packages get defined cleanly.

Step 3 — Package each CWP user

CWP's built-in User Backups tool creates a per-account .tar.gz containing web roots, databases, mail, DNS zones, FTP accounts, and the user's cron — everything you need in one file. It's not in pkgacct format (so cPanel's transfer wizard can't ingest it directly), but the contents extract cleanly with tar and the pieces map onto cPanel paths.

On the source, generate a fresh backup for each user via the CWP CLI:

USER=customerone
/scripts/cwp_backup_user $USER
ls -lh /home/cwp-backup/${USER}-*.tar.gz | tail -1

The backup lands at /home/cwp-backup/<user>-YYYY-MM-DD.tar.gz. Inside, the structure is:

home/<user>/
├── public_html/       # primary domain web root
├── public_html_addon/ # addon and subdomains (if any)
mysql/                 # per-database mysqldump output
mail/                  # Maildir trees pulled out of /home/vmail
dns/                   # BIND zone files
account.info           # quotas, package, contact email, plain-password (Free) or salted (Pro)

Move the tarball to the destination via rsync — it's resumable and a mail-heavy account can easily be 30+ GB:

rsync -P /home/cwp-backup/${USER}-*.tar.gz destination:/home/

Step 4 — Restore each user as a cPanel account

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

With the account created, restore the pieces:

CUSER=customer1                     # cPanel username
HUSER=customerone                   # CWP username
TARBALL=/home/${HUSER}-*.tar.gz

mkdir -p /tmp/cwp-restore-$CUSER
tar -xzf $TARBALL -C /tmp/cwp-restore-$CUSER

# Web files — primary domain into public_html
rsync -av /tmp/cwp-restore-$CUSER/home/$HUSER/public_html/ \
  /home/$CUSER/public_html/
chown -R $CUSER:$CUSER /home/$CUSER/public_html

# Databases — CWP has no enforced prefix, cPanel requires <cuser>_
for sql in /tmp/cwp-restore-$CUSER/mysql/*.sql; do
  oldname=$(basename $sql .sql)
  newname="${CUSER}_${oldname}"
  mysql -e "CREATE DATABASE \`$newname\`"
  mysql $newname < $sql
done

# Mail — convert /home/vmail layout to cPanel /home/<user>/mail
for maildomain in /tmp/cwp-restore-$CUSER/mail/*/; do
  d=$(basename $maildomain)
  for acct in $maildomain/*/; do
    local_part=$(basename $acct)
    mkdir -p /home/$CUSER/mail/$d/$local_part
    rsync -av $acct/Maildir/ /home/$CUSER/mail/$d/$local_part/
  done
done
chown -R $CUSER:$CUSER /home/$CUSER/mail

The database rename is the step people skip and then waste an hour debugging "this database is not visible in cPanel". cPanel enforces the <cpaneluser>_ prefix and rejects operations on databases that don't match.

After the file restore, update any wp-config.php, configuration.php, or settings.php to point at the renamed databases and the new MySQL passwords cPanel generated:

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

Step 5 — Recreate mail accounts and DKIM

The Maildir data is now in place on disk, but cPanel needs each 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. Set the same password the customer was using (CWP Pro stores these salted, CWP Free keeps them retrievable from root_cwp.email_accounts), or force a reset and notify them in advance.
  3. Re-publish DKIM. CWP generates DKIM keys per domain under /etc/opendkim/keys/<domain>/ and those keys are not portable to cPanel's Exim-based DKIM. 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 before the DNS cutover.

The Postfix-to-Exim mail server transition is the most visible change for customers. Folder structure and read/unread flags carry over from the Maildir copy, but anything stored in Sieve filters on CWP needs to be reconfigured in cPanel's webmail filters — Sieve scripts under /home/vmail/<domain>/<acct>/sieve/ are syntactically compatible but the path and delivery agent differ enough that copying them in raw rarely works.

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-CWP AutoSSL failures are stale CAA records published by CWP's certbot integration that pin issuance to Let's Encrypt and exclude the Sectigo CA that cPanel AutoSSL defaults to.

Step 7 — Decommission carefully

Leave the CWP 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 — any mail delivered to the old /home/vmail/ tree 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. Unlike CyberPanel — where there's a clear security argument for never reusing the OS image — a patched CWP box is a clean enough Linux install to repurpose if you want, though most operators take the migration as the moment to standardise on a fresh AlmaLinux 9 build for the next server too.

FAQ

Can I use cPanel's transfer wizard to import a CWP account?+
No. cPanel's transfer tool ingests pkgacct archives from cPanel, Plesk, DirectAdmin, and a handful of legacy panels — CWP is not in the list. The migration is account-by-account: package the user with cwp_backup_user, create the cPanel account in WHM, extract files and Maildirs, restore databases with the new prefix, recreate mail accounts.
Does CWP's free-tier license cause migration problems?+
No, the CWP Free vs Pro licence affects what runs on the source server, not what you can copy off it. User backups work on both tiers. CWP Pro accounts store mailbox passwords salted, so on a Pro source you'll need a customer-side reset at cutover; on Free you can read passwords from root_cwp.email_accounts and reuse them.
How do I convert Postfix mail storage to cPanel's Exim layout?+
The Maildir contents are byte-compatible — Dovecot wrote them the same way on both panels. You only need to move them from /home/vmail/<domain>/<acct>/Maildir/ to /home/<cpaneluser>/mail/<domain>/<acct>/ and fix ownership to the cPanel user. After that, create the matching mailbox in cPanel's Email Accounts so IMAP knows to serve the folder.
Will customer mailbox passwords survive the migration?+
On CWP Free, yes — mailbox passwords are stored retrievable in the root_cwp.email_accounts table and you can set the same password on the new cPanel mailbox. On CWP Pro, passwords are salted and unrecoverable; plan a customer-side reset at cutover and notify subscribers a few days in advance.
What happens to DKIM keys when I move from CWP to cPanel?+
CWP's OpenDKIM keys under /etc/opendkim/keys/<domain>/ don't port to cPanel's Exim-based DKIM. Generate fresh keys in cPanel's Email Deliverability tool per domain, publish the new selector record at the registrar before the DNS cutover, and let inbox providers re-key cleanly rather than trying to reuse the old key.
How long does a CWP to cPanel migration take?+
Plan 25-35 minutes of operator time per account plus 15-30 minutes of customer-visible downtime per DNS cutover. A 25-user CWP server is one full operator-day spread across two evenings if you stagger cutovers across the customer base.

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.