KnowledgebaseMail Server › Migrating mail accounts off cPanel onto a self-managed VPS

Migrating mail accounts off cPanel onto a self-managed VPS

You've decided to stop paying for cPanel hosting and run your mail on a LYLIX VPS instead. The web is plastered with "use our paid tool to migrate" articles; this one is the open-source path that takes a weekend of operator time and zero recurring software cost. Assumes you've already set up Postfix + Dovecot on the new VPS (see related articles) and you're ready to move the actual data.

The migration in one breath

  1. Stand up Postfix + Dovecot on the new VPS, configure all the accounts that exist on cPanel.
  2. Use imapsync to copy mail from cPanel's IMAP server to the new VPS's IMAP, per account.
  3. Lower DNS TTL on the MX record well in advance.
  4. Cut MX over to the new VPS. New mail flows there immediately; existing mail finishes syncing.
  5. Run imapsync one more time for the residual gap mail. Decommission cPanel.

Total downtime: zero, if you do it right. Some mail might land at the old MX during the cutover window and need a residual sync.

Step 1: enumerate what's on cPanel

Log into cPanel → Email Accounts. Note each address, current mailbox size, password (or reset to a known one for the migration — you'll change them again afterward).

Also note:

  • Mail filters / Sieve rules per account (cPanel calls these "Email Filters").
  • Forwarders (Email Forwarding).
  • Auto-responders (Auto Responders).
  • Mailing lists if any.

Print these or save to a file. cPanel's "Backup" doesn't always export forwarders/filters cleanly.

Step 2: replicate the account structure on the new VPS

For each cPanel address, create a virtual mailbox + Dovecot user on the new VPS. See the mail-aliases-and-catchall article for the Postfix virtual_mailbox setup; Dovecot auth typically points at a passwd-file or SQL backend.

Set the password the same as on cPanel for the migration window — imapsync needs both ends to authenticate, and matching passwords avoid a credentials map.

Create the forwarders as virtual_alias entries; recreate the auto-responders via Sieve (if you have Sieve configured) or via a simple Postfix transport that runs a vacation autoresponder.

Step 3: imapsync — the actual mail copy

Install imapsync on any machine that can reach both servers (the new VPS works fine):

apt install imapsync           # Debian/Ubuntu
# AlmaLinux: install from CPAN or use the Docker image

Per-account command:

imapsync \
  --host1 mail.oldhost.com --user1 alice@example.com --password1 'OLD_PW' \
  --host2 mail.newvps.example.com --user2 alice@example.com --password2 'NEW_PW' \
  --ssl1 --ssl2 \
  --automap --skipcrossduplicates \
  --logdir /var/log/imapsync \
  --logfile alice-$(date +%F).log

For multiple accounts, script the loop:

#!/bin/bash
# /usr/local/bin/migrate-mail.sh
while IFS=: read -r email old_pw new_pw; do
    echo "Syncing $email ..."
    imapsync --host1 mail.oldhost.com --user1 "$email" --password1 "$old_pw" \
             --host2 mail.newvps.example.com --user2 "$email" --password2 "$new_pw" \
             --ssl1 --ssl2 --automap --skipcrossduplicates \
             --logdir /var/log/imapsync --logfile "${email}-$(date +%F).log"
done < /etc/imapsync/accounts.txt

Where accounts.txt is email:old_pw:new_pw one per line, mode 0600. Run this initial sync while cPanel is still your live mail — could take hours per account for large mailboxes (rule of thumb: 10–30 GB per hour over a typical link).

Step 4: DNS lowering, then cutover

Several days before the cutover, lower your MX record's TTL to 300 (5 minutes). DNS caches everywhere will pick this up gradually; by cutover day, resolvers will see the new MX within 5 minutes of the change.

At cutover:

  1. Change MX record to point at the new VPS.
  2. Wait the TTL period (5 minutes).
  3. From the new VPS, verify external test mail arrives: send from a Gmail to alice@example.com, watch the new VPS's logs.
  4. Re-run imapsync ONE MORE TIME for any mail that landed at the old MX during the cutover. This catches the gap.

Step 5: validate, then decommission

  • For each migrated account, log in via Thunderbird / phone client to the new server. Verify folder structure, message counts, attachments load, sent mail folder is right.
  • Test sending FROM each address — make sure SPF / DKIM / DMARC are all happy at the new server (see the related articles on each).
  • For a week, leave cPanel running in case you need the original as a reference. Watch for late-arriving mail there; re-sync if needed.
  • After a week of clean operation: cancel cPanel.

Common gotchas

  • Folder naming differs. cPanel/Roundcube uses INBOX.Sent, Dovecot uses Sent. imapsync's --automap handles this for the standard folders; custom folders may need --folder INBOX.MyFolder=MyFolder mappings.
  • Date discrepancies on transferred messages. Some IMAP servers reset the INTERNALDATE on copy; --syncinternaldates preserves the original.
  • Large attachments fail. Some IMAP servers have message-size limits. --maxsize 100000000 caps imapsync at 100 MB per message; messages larger than that get skipped with a warning.
  • SSL cert mismatches. If cPanel's IMAP cert is self-signed or expired, add --sslargs1 SSL_verify_mode=0 to skip verification on the SOURCE only.
  • Sender domain reputation. Outbound mail from your new VPS IP has zero reputation. Plan for SPF + DKIM + DMARC to be in place BEFORE cutover, and watch deliverability in the first weeks. See the sender warmup article.

Also Read

« « Back

Powered by WHMCompleteSolution