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
- Stand up Postfix + Dovecot on the new VPS, configure all the accounts that exist on cPanel.
- Use imapsync to copy mail from cPanel's IMAP server to the new VPS's IMAP, per account.
- Lower DNS TTL on the MX record well in advance.
- Cut MX over to the new VPS. New mail flows there immediately; existing mail finishes syncing.
- 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:
- Change MX record to point at the new VPS.
- Wait the TTL period (5 minutes).
- From the new VPS, verify external test mail arrives: send from a Gmail to alice@example.com, watch the new VPS's logs.
- 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
--automaphandles this for the standard folders; custom folders may need--folder INBOX.MyFolder=MyFoldermappings. - Date discrepancies on transferred messages. Some IMAP servers reset the INTERNALDATE on copy;
--syncinternaldatespreserves the original. - Large attachments fail. Some IMAP servers have message-size limits.
--maxsize 100000000caps 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=0to 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
Powered by WHMCompleteSolution