Goals of a clean migration
- Website files and database match on the destination
- TLS works on the new host before or immediately at cutover
- Visitors and search engines land on the correct hostname
- Email keeps working if mail is not hosted on the same server you are leaving
Write down:
- All hostnames in use ([font=monospace]example.com[/font], [font=monospace]www[/font], staging names, CDN CNAMEs).
- Where email lives (Google Workspace, Microsoft 365, the same cPanel box, etc.).
- Current TTL on the A/AAAA records you will change (if TTL is 86400, lower it to 300–600 a day before cutover).
- PHP version and required extensions on the source.
- Cron jobs, [font=monospace].env[/font] / config paths, and scheduled backups.
- Create the web space and database on the new host.
- Copy files (SFTP, rsync, or host migration tool). Preserve permissions for writable dirs ([font=monospace]uploads[/font], [font=monospace]cache[/font], [font=monospace]storage[/font]).
- Export the database from the source ([font=monospace]mysqldump[/font] or panel export) and import on the destination.
- Update application config:
- DB host/name/user/password
- Any hard-coded old paths
- For WordPress, run a controlled search-replace for URLs if the temporary test URL differs (WP-CLI [font=monospace]search-replace[/font] with extras serialization support—not raw SQL replace on PHP serialized data).
- Test using a hosts file override or host-provided preview URL so the public DNS remains unchanged.
- Home page and one deep inner page load
- Admin/login works
- Forms send (or at least submit without 500)
- HTTPS certificate issues resolved on the new stack (or plan HTTP→HTTPS after cert issuance)
- File uploads to media/storage succeed
- No mixed content on a sample page (browser dev tools console)
Typical website-only change:
Record — Action
`A` / `AAAA` for `@` — Point to **new** web server IP
`www` CNAME or A — Match new hosting docs
`MX` — **Do not touch** if email is external
TXT SPF/DKIM/DMARC — Leave alone unless mail is also moving
CDN — Update origin IP/hostname per CDN dashboard
After change:
- Query from multiple resolvers ([font=monospace]dig[/font] + a public DNS checker).
- Expect mixed results until TTL expires.
- Keep the old host read-only for a soak period if you can (hours to a few days) in case you must roll back the A record.
- Force HTTPS if certificates are live.
- Update sitemap/Search Console property if the host or property verification method changed.
- Purge CDN.
- Re-test cron (hosting cron vs application cron).
- Confirm backups now run on the new host.
- Only decommission the old host after you are sure nothing still points there (including API callbacks and payment webhooks).
- Sync [font=monospace]wp-config.php[/font] salts only if intentional; do not paste secrets into tickets.
- Object cache (Redis/Memcached) must be re-pointed or disabled on the new host.
- Multisite domain maps need explicit domain updates—do not treat like single-site.
- If you use a reverse proxy, ensure real IP and HTTPS detection headers match what WordPress expects ([font=monospace]HTTPS[/font] / [font=monospace]X-Forwarded-Proto[/font] handling).
Symptom after cutover — Check
Old site still appears — TTL/cache/CDN; confirm dig for your public IP
DB connection error — Config credentials; remote DB host firewall
Redirect loop — HTTPS settings + proxy headers + canonical redirects
Missing images — Files not copied; wrong uploads path; hotlink to old host
Mail stopped — Someone changed MX/SPF while editing zone for web
Rollback
If the new site is broken in production:
- Point A/AAAA back to the old IP (if old host still has the last good copy).
- Fix on destination with hosts-file testing.
- Cut over again only after pre-flight passes.
Migrate content first, test privately, then move only the DNS records that belong to the website. Protect email records, keep a rollback window, and treat post-cutover HTTPS, cron, and backups as part of the job—not optional cleanup.