
A control panel move is where good admin habits either save you hours or cost you a weekend. This control panel migration tutorial shows how to move a production domain from cPanel/WHM to DirectAdmin on a new VPS without breaking mail, SSL, or DNS.
The goal is intentionally boring. You want no surprises for users, no missing mail, and a rollback you can execute in minutes.
You’ll stage the new server, migrate web + databases + mail, cut DNS after lowering TTL, then verify with checks you can trust.
What you’ll migrate (and what you should not)
Decide the scope before you touch anything. This guide assumes one domain (or a small set) with a typical shared-hosting stack: site files, databases, mailboxes, and DNS records.
- Web: document root, uploads, app files, cron jobs
- Database: MySQL/MariaDB dumps and users
- Mail: IMAP mailboxes (Maildir), forwarders, catch-alls (if you still use them)
- SSL: Let’s Encrypt re-issuance on the new server (prefer re-issue over copying keys)
- DNS: A/AAAA, MX, TXT (SPF/DKIM/DMARC), CNAMEs, SRV if present
Leave behind anything you can’t explain to another admin.
That includes abandoned subdomains, old staging installs, and mystery DNS records that nobody “owns” anymore.
Prerequisites and planning checklist (15 minutes that prevents rework)
Build the destination VPS with breathing room. If the current cPanel server already runs hot, matching that sizing just recreates the bottleneck.
NVMe storage matters too. It makes imports, mailbox copies, and cache rebuilds much less painful.
If you’d rather not spend migration day also doing OS hardening and baseline tuning, managed VPS hosting from HostMyCode is a practical fit for control-panel workloads. You focus on moving and validating. They keep the foundation tidy.
- Source: cPanel/WHM server access (root SSH and WHM access)
- Destination: fresh VPS (Ubuntu 24.04 LTS or AlmaLinux 9/10 are common in 2026)
- DirectAdmin: license + installer ready
- DNS access: where your nameservers/zone live (registrar, Cloudflare, etc.)
- Lower TTL: plan to reduce DNS TTL to 300 seconds 24 hours before cutover
- Maintenance window: even “zero downtime” moves have a quiet period for final sync
Quick inventory commands on the source cPanel box:
# Domains and docroots (cPanel)
awk '{print $1"\t"$2}' /etc/userdatadomains | head -n 30
# Mail accounts (per cPanel account)
ls -1 /home/*/mail 2>/dev/null | head
# Databases overview (root)
mysql -e "SHOW DATABASES;" | head
Step 1: Provision the new VPS and install DirectAdmin cleanly
Start with a clean OS image. Don’t “upgrade in place” from an old template and hope for the best.
If you’re still shopping for infrastructure, a fresh HostMyCode VPS lets you pick the OS and size CPU/RAM to the workload you’re moving.
Baseline OS prep (Ubuntu example):
sudo apt update
sudo apt -y upgrade
sudo reboot
After reboot, set the hostname and confirm it resolves correctly.
Mail problems love bad hostnames.
sudo hostnamectl set-hostname da1.example.com
# Verify FQDN resolution
getent hosts da1.example.com
hostname -f
If you’ve been burned by SMTP banner/HELO mismatches before, keep this guide handy: email server hostname setup.
Install DirectAdmin using their official method for your OS. During setup, stick to sane defaults:
- Use Let’s Encrypt integration (you’ll re-issue certificates later)
- Enable spam filtering, but keep aggressive blocking off until after deliverability checks
- Choose PHP-FPM (common in 2026 for multi-site hosting)
Firewall note: open only what you need (SSH, HTTP/HTTPS, SMTP/IMAP if you host mail). Don’t run with “allow all” just because you’re migrating.
If you need a WHM-specific firewall walkthrough, keep it limited to the source: cPanel firewall setup guide.
Step 2: Lower DNS TTL (so cutover behaves like you expect)
This is where most “no downtime” claims quietly fail. If your TTL is 86400, plenty of users will keep hitting the old server all day.
Lower TTL ahead of time, not during the move.
- At your current DNS host, set A/AAAA/MX TTL to 300.
- Wait at least the prior TTL period (often 24 hours).
If you’re not sure whether the change is actually live outside your network, use this workflow: DNS propagation troubleshooting.
Step 3: Create matching users/domains on DirectAdmin (staging phase)
On the destination, create the DirectAdmin user and domain first. Use clean usernames.
Skip legacy cPanel names with odd punctuation or cramped abbreviations.
While you stage, keep public DNS exactly as-is.
Validate the new server via /etc/hosts and direct IP testing.
Local testing with hosts file (from your laptop):
# On Linux/macOS: /etc/hosts
203.0.113.10 example.com www.example.com
That forces your machine to load the new server while everyone else stays on the old one.
Step 4: Migrate website files with rsync (repeatable, fast, and safe)
rsync is the workhorse here. It’s faster than “download then upload,” and it’s easy to repeat.
Run it once for the bulk copy. Run it again during the maintenance window to catch the last changes.
Find the docroot on cPanel (common examples):
- Main domain:
/home/USER/public_html/ - Addon domain:
/home/USER/public_html/addondomain.tld/(varies)
Run rsync from destination (recommended):
# On DirectAdmin server
sudo rsync -aHAX --numeric-ids --info=progress2 \
-e "ssh -p 22" root@OLD_SERVER_IP:/home/USER/public_html/ \
/home/DAUSER/domains/example.com/public_html/
Pitfall: WordPress and similar apps will bring cache directories along for the ride. That’s fine.
After cutover, purge caches and regenerate permalinks once. This helps you avoid chasing stale output.
If you want stricter, repeatable file-transfer practices beyond this one migration, use: SFTP setup guide tutorial.
Step 5: Migrate databases and users (and fix the app config)
Most cPanel environments run MariaDB. DirectAdmin often does too, but versions won’t always match.
Use logical dumps. They keep you out of version-mismatch traps.
On the source server: dump the database:
mysqldump --single-transaction --routines --triggers \
-u root -p DBNAME | gzip > DBNAME.sql.gz
Copy the dump to destination:
scp DBNAME.sql.gz root@NEW_SERVER_IP:/root/
On the destination: create DB + user, then import:
# Create DB and user in DirectAdmin panel (preferred), then:
cd /root
gunzip -c DBNAME.sql.gz | mysql -u root -p NEWDBNAME
Update application config (examples):
- WordPress:
wp-config.php→DB_NAME,DB_USER,DB_PASSWORD,DB_HOST - Laravel:
.env→DB_*
Quick WordPress DB check (CLI):
php -v
php -r 'echo "PHP OK\n";'
# If you use wp-cli
wp core version --path=/home/DAUSER/domains/example.com/public_html
Step 6: Migrate mailboxes without breaking deliverability
If you host email on the same server, treat mail as its own track. The failure modes are different from web issues.
Common problems include missing messages, clients re-downloading huge folders, and deliverability drops because DNS didn’t keep up.
Decide your mail strategy first:
- Keep mail on-server: move Maildir + recreate accounts in DirectAdmin
- Move mail to a third-party provider: migrate IMAP and change MX (outside scope here)
Mailbox copy approach (Maildir):
- Create the same email accounts in DirectAdmin (usernames, quotas, passwords).
- Copy Maildir content from cPanel to DirectAdmin.
- Fix ownership/permissions.
Paths vary by configuration. A common cPanel path is:
/home/USER/mail/example.com/ACCOUNT/
A common DirectAdmin path is:
/home/DAUSER/imap/example.com/ACCOUNT/Maildir/(or similar depending on DA build)
Example rsync for mail (adjust paths to your servers):
# On destination
sudo rsync -aHAX --numeric-ids --delete \
root@OLD_SERVER_IP:/home/USER/mail/example.com/ \
/home/DAUSER/imap/example.com/
Deliverability must-haves after cutover:
- Correct hostname + matching rDNS/PTR
- SPF updated for the new sending IP
- DKIM re-generated (or migrated carefully) and published in DNS
- DMARC record present and aligned
For the DNS side of mail, use this as your checklist: VPS email setup tutorial.
Step 7: Re-issue SSL on DirectAdmin (don’t copy certs unless you must)
Copying private keys between servers widens your risk surface and creates long-term certificate clutter.
In 2026, Let’s Encrypt automation is stable enough that re-issuing is usually the cleaner move.
Before issuing, ensure:
- DNS A/AAAA for the domain points to the new server (or you use a temporary validation method)
- Port 80 is reachable for HTTP-01 (unless using DNS-01)
After cutover, issue certificates for:
example.comwww.example.com- Any subdomains that need HTTPS
If renewal or validation fails, this troubleshooting flow saves time: SSL renewal troubleshooting.
Step 8: Cut over DNS (A/AAAA + MX + key TXT records)
Now you switch public traffic. With TTL already lowered, most clients should follow within minutes, not hours.
Minimum DNS changes:
- A/AAAA: point
example.comandwwwto NEW_SERVER_IP - MX: if you host mail on the VPS, point MX to the new hostname/IP
- SPF TXT: update to include the new IP (and remove the old one later)
- DKIM TXT: publish DirectAdmin’s DKIM selector record
- DMARC TXT: keep policy consistent, start with
p=noneif you’re unsure
Verify DNS from a terminal:
# Replace resolver if you want (e.g., 1.1.1.1 or 8.8.8.8)
dig +short example.com A
dig +short www.example.com A
dig +short example.com MX
dig +short example.com TXT
If you want a repeatable cutover playbook for future moves, use: DNS cutover checklist.
Step 9: Do a final sync and flip the site to “read-write” on the new server
Active sites change while you’re migrating. Orders, comments, uploads, and scheduled jobs keep coming.
Pick a write strategy before cutover. Don’t improvise mid-move.
- Short maintenance window: enable maintenance mode, run final rsync + DB dump/import, then disable
- Freeze writes: disable forms/checkout briefly
- Accept a small gap: fine for brochure sites, not fine for stores
WordPress quick approach:
- Enable a maintenance page/plugin on the old server.
- Run final
rsyncfor files. - Do a fresh DB dump/import.
- Switch DNS (or confirm it already moved), then disable maintenance.
Step 10: Post-cutover verification (web, mail, SSL, and logs)
Don’t stop at “it loads for me.” Use checks that catch partial failures fast, before users do.
Web checks
- Homepage loads over HTTPS (no certificate warning)
- Login works (WordPress admin, app admin)
- Contact form sends mail (and doesn’t land in spam)
- Uploads work (permissions and PHP limits)
Command checks:
curl -I https://example.com/
# Look for 200/301 and correct server header/chain
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject -dates
Mail checks
- IMAP login works from a real client
- Outbound mail passes SPF/DKIM
- SMTP banner and HELO match a valid FQDN
Log checks (first hour after cutover)
Spend the first hour watching for the usual suspects.
Look for 500s, permission denials, missing PHP modules, and bots pounding endpoints that no longer exist.
# Paths vary; adjust for your web server
sudo tail -n 200 /var/log/nginx/error.log
sudo tail -n 200 /var/log/apache2/error.log
sudo tail -n 200 /var/log/mail.log
Disk usage often jumps right after a move (logs, caches, leftover backups).
If space gets tight, use: VPS disk space troubleshooting.
Rollback plan (simple, realistic, and fast)
Your fastest rollback handle is DNS. Keep the old server online for at least 48–72 hours.
Resist the urge to cancel it the same day you cut over.
- If web is broken: switch A/AAAA back to the old IP, then fix calmly.
- If mail is broken: switch MX back, then resolve hostname/rDNS/SPF/DKIM issues.
- Keep a note of every DNS change you made (especially TXT records).
If you manage your own infrastructure, snapshots make rollbacks much less stressful.
This guide pairs well with migrations: snapshot backup tutorial.
Common migration problems and quick fixes
- Site loads old content after DNS cutover: your local resolver cached it. Flush DNS, check with
digagainst 1.1.1.1 and 8.8.8.8. - SSL fails on new server: port 80 blocked, wrong vhost, or DNS still points to old IP. Validate with
curl -I http://example.com. - WordPress redirect loop: wrong site URL or forced HTTPS behind proxy. Check
wp_optionssiteurl/home and any caching plugin settings. - Mail sent but not received: MX still points old, or SPF/DKIM mismatch. Verify TXT records and mail logs.
- Permissions errors after rsync: wrong ownership in docroot. Fix with a targeted
chownfor the domain directory (avoid recursive chmod 777).
Summary: a safe control panel move is mostly sequencing
This job is mostly order of operations. Lower TTL, stage DirectAdmin, migrate files and databases, handle mail carefully, cut DNS, then verify with real checks.
Do it in that sequence and the move feels quiet.
If you want a predictable platform for control-panel hosting (with room to scale as you add accounts), start with a HostMyCode VPS. If you’d rather spend your time on customer work instead of OS upkeep, managed VPS hosting is a straightforward way to run cPanel/DirectAdmin-style workloads at production quality.
Planning a control-panel switch and want the infrastructure side handled cleanly? HostMyCode can provision a right-sized VPS and help you avoid the common migration pitfalls. For hands-off server upkeep, choose managed VPS hosting. If you want full control, start with a HostMyCode VPS and work through the checklist above.
FAQ
Can I migrate from cPanel to DirectAdmin with zero downtime?
You can get very close for most sites. Database-driven apps still need a short “final sync” window unless you implement application-level replication.
Plan for 5–20 minutes of reduced writes.
Should I copy SSL certificates from cPanel to DirectAdmin?
Usually no. Re-issue Let’s Encrypt certificates after cutover.
Copying private keys increases risk and tends to create messy certificate inventory later.
What’s the safest way to migrate email mailboxes?
Create matching accounts first, then rsync Maildir data, then validate via IMAP from a real client.
Keep the old server online for a few days in case a mailbox was missed.
How long should I keep the old server after the migration?
Keep it for at least 48–72 hours. That covers straggler DNS caches and gives you time to confirm mail and cron jobs behave normally.
What’s the most common cause of post-migration email deliverability issues?
Incorrect hostname/rDNS and stale SPF/DKIM records.
Verify your SMTP banner, PTR record, and TXT records immediately after cutover.