Introduction: Why Server Migrations Happen
At some point, every server administrator faces the inevitable: you need to move everything to a new server. Maybe your current provider raised prices, perhaps you have outgrown your hardware, or your company is consolidating infrastructure. Whatever the reason, server migration is one of the highest-stakes operations in system administration. A smooth migration means zero or near-zero downtime. A botched migration means lost email, broken websites, and angry users.
This guide provides a comprehensive, battle-tested checklist for migrating websites, databases, email, and services to a new server. We will cover every phase: planning, preparation, data transfer, testing, DNS cutover, and post-migration verification. Follow this guide step by step, and you will achieve a migration with minimal disruption.
Phase 1: Discovery and Inventory
Before touching any server, you need a complete inventory of everything that will be migrated. Missing even one component can cause cascading failures after the switch.
Complete Inventory Checklist
Websites and Applications
- List all domains and subdomains hosted on the server
- Document the web server (Nginx, Apache) and its configuration
- Note PHP versions used by each site
- Identify application frameworks (WordPress, Laravel, Django, Node.js)
- Record document root paths for each site
- Check for custom Nginx/Apache rewrite rules
Databases
- List all MySQL/MariaDB databases and their users
- List all PostgreSQL databases and roles
- Record database sizes (for transfer time estimates)
- Note any replication configurations
- Document connection strings in application configs
- Check for scheduled database maintenance tasks
- List all email accounts and their mailbox sizes
- Document email forwarders and aliases
- Record autoresponder configurations
- Note spam filter settings and whitelists
- Check for DKIM keys that need to be transferred
- Document mailing list configurations
System Services
- List all cron jobs for every user
- Document SSL certificates and their expiry dates
- Record FTP/SFTP accounts
- Note firewall rules and fail2ban configurations
- Check for custom system services
- Document DNS zones if running a nameserver
Phase 2: Pre-Migration Preparation
Reduce DNS TTL (24-48 Hours Before)
This is the single most important preparation step. DNS changes propagate based on TTL (Time To Live) values. If your current TTL is 86400 (24 hours), DNS clients worldwide will cache your old IP for up to 24 hours after you change it.
$ dig +short +ttlid example.com @8.8.8.8
300 IN A 203.0.113.10
$ dig +short +ttlid example.com @1.1.1.1
300 IN A 203.0.113.10
Set Up the New Server
Prepare the new server with all required software before starting any data transfer:
- Install the same OS version (or newer with compatibility verified)
- Install web server (Nginx/Apache) with matching configuration
- Install all required PHP versions with the same extensions
- Install and configure database servers (MySQL, PostgreSQL)
- Install mail server components if migrating email
- Configure firewall rules to match the old server
- Set up the same user accounts and directory structure
Phase 3: Data Transfer
File Transfer with rsync
rsync is the gold standard for server file migration because it transfers only the differences between source and destination, supports compression, preserves permissions, and can resume interrupted transfers.
$ rsync -avz --info=progress2 \
-e "ssh -p 22" \
root@old-server:/var/www/ \
/var/www/
sending incremental file list
12.45G 100% 45.23MB/s 0:04:36 (xfr#8234, to-chk=0/12847)
# Exclude unnecessary files
$ rsync -avz --info=progress2 \
--exclude='*.log' \
--exclude='cache/*' \
--exclude='node_modules/' \
-e "ssh -p 22" \
root@old-server:/var/www/ /var/www/
Database Migration
MySQL / MariaDB
$ mysqldump --all-databases --single-transaction \
--routines --triggers --events \
-u root -p > /tmp/all_databases.sql
# Transfer to new server
$ rsync -avz /tmp/all_databases.sql root@new-server:/tmp/
# Import on new server
$ mysql -u root -p < /tmp/all_databases.sql
PostgreSQL
$ pg_dumpall -U postgres > /tmp/all_pg_databases.sql
# Import on new server
$ psql -U postgres -f /tmp/all_pg_databases.sql
--flush-privileges or run FLUSH PRIVILEGES after import. Database user password hashes must be preserved exactly — do not attempt to recreate users with new passwords unless absolutely necessary.
Email Migration
Email migration requires special care because email is continuously flowing. Here are the key approaches:
| Method | Downtime | Complexity | Best For |
|---|---|---|---|
| Maildir copy via rsync | Minutes | Low | Same mail server software on both servers |
| IMAP sync (imapsync) | Zero | Medium | Different mail server software |
| Backup and restore | Hours | Low | Complete server clones |
$ rsync -avz --info=progress2 \
root@old-server:/var/mail/ /var/mail/
# IMAP-to-IMAP sync (preserves flags, folders)
$ imapsync \
--host1 old-server --user1 [email protected] --password1 'pass' \
--host2 new-server --user2 [email protected] --password2 'pass'
Phase 4: Testing Before DNS Switch
This is where most administrators cut corners — and where most migration failures originate. Never switch DNS without thorough testing.
Test Using Hosts File
Edit your local /etc/hosts file (or C:\Windows\System32\drivers\etc\hosts on Windows) to point domains to the new server IP without affecting anyone else:
198.51.100.50 example.com
198.51.100.50 www.example.com
198.51.100.50 mail.example.com
198.51.100.50 shop.example.com
Verification Checklist
Website Testing
- Homepage loads correctly with all assets (CSS, JS, images)
- Internal pages and navigation work
- Contact forms submit successfully
- Login and authentication work
- Database-driven content displays correctly
- File uploads function properly
- SSL certificates are valid and not expired
- HTTP-to-HTTPS redirects work
Backend Testing
- Database connections work from all applications
- Cron jobs are configured and scheduled
- Email sending works (test with a form)
- Email receiving works (send a test email)
- FTP/SFTP access works for all accounts
- PHP versions match what each site requires
- File permissions are correct
- Log files are being written
Phase 5: DNS Cutover
Once testing is complete and everything checks out on the new server, it is time for the DNS switch. This is the point of no return, so be methodical:
Migration Day Timeline
(catch deltas)
& import
new server
records
propagation
traffic flow
$ rsync -avz --delete -e "ssh -p 22" \
root@old-server:/var/www/ /var/www/
# Step 2: Final database sync
$ ssh root@old-server "mysqldump --all-databases \
--single-transaction" | mysql -u root -p
# Step 3: Update DNS A records to new server IP
# (Do this in your DNS provider's control panel)
# example.com A 198.51.100.50 (new IP)
# www.example.com A 198.51.100.50 (new IP)
# mail.example.com A 198.51.100.50 (new IP)
Monitoring DNS Propagation
$ dig +short example.com @8.8.8.8
198.51.100.50
$ dig +short example.com @1.1.1.1
198.51.100.50
$ dig +short example.com @208.67.222.222
198.51.100.50
Phase 6: Post-Migration
Immediately After DNS Switch
- Monitor server access logs to confirm traffic is arriving at the new server
- Check error logs for any 500 errors or missing files
- Verify email delivery by sending test emails to and from all domains
- Test all critical application workflows (registration, checkout, etc.)
- Monitor server resource usage (CPU, memory, disk I/O)
- Check SSL certificate validity from external SSL checkers
Keep the Old Server Running
Restore DNS TTL
Once everything is confirmed working on the new server (typically after 48-72 hours), raise the DNS TTL back to a normal value (3600 or 86400 seconds). Low TTL values increase DNS query volume, which is unnecessary once the migration is complete.
Common Migration Pitfalls
Hardcoded IP Addresses
Applications may have the old server IP hardcoded in configuration files, database connection strings, or even content. Search for the old IP across all files:
grep -r "203.0.113.10" /var/www/ --include="*.php" --include="*.conf"
Missing PHP Extensions
A website works on the old server but shows errors on the new one because a PHP extension (like imagick, redis, or intl) is not installed. Compare php -m output between both servers.
File Permission Differences
rsync preserves permissions, but if user IDs differ between servers, files may end up with wrong ownership. Always verify ownership after transfer with ls -la.
SSL Certificate Issues
SSL certificates are tied to the domain, not the server. Transfer existing certificates or issue new ones (Let's Encrypt) before the DNS switch. Do not switch DNS to a server that shows SSL warnings.
Migration Timeline Template
| Timeframe | Action | Risk Level |
|---|---|---|
| T-7 days | Complete inventory and set up new server | Low |
| T-48 hours | Lower DNS TTL to 300 seconds | Low |
| T-24 hours | Initial rsync and database transfer | Low |
| T-12 hours | Complete testing via hosts file | Low |
| T-0 (migration window) | Final rsync, final DB dump, DNS switch | Medium |
| T+1 hour | Verify DNS propagation and test all sites | Medium |
| T+24 hours | Monitor logs and fix any remaining issues | Low |
| T+7 days | Raise DNS TTL, decommission old server | Low |
How Panelica Handles Server Migration
Panelica's migration tool automates the entire process:
source server
all sites
via rsync
(preserved hashes)
accounts
certificates
- Automatic site discovery from the source server via secure API connection
- rsync-based file transfer with real-time progress tracking in the web interface
- Database import with preserved password hashes — users do not need to reset passwords
- Email account migration including mailbox contents, forwarders, and autoresponders
- SSL certificate issuance via Let's Encrypt after domain verification
- Visual pipeline with checkpoint progress so you can monitor every phase
Conclusion
Server migration does not have to be stressful. With proper planning, a complete inventory, the DNS TTL trick, thorough testing before the switch, and a methodical cutover process, you can achieve near-zero downtime migrations. The key principles are: never rush the DNS switch, always test via hosts file first, keep the old server running as a safety net, and have a rollback plan ready. Whether you are migrating a single WordPress site or hundreds of domains, this checklist will keep you on track and your users happy.