Back to tutorials
Tutorial

Hosting Migration Checklist Tutorial (2026): Move a Website to a New VPS Without Downtime

Hosting migration checklist tutorial for 2026: move your site to a new VPS safely with DNS, SSL, email, and rollback steps.

By Anurag Singh
Updated on Aug 01, 2026
Category: Tutorial
Share article
Hosting Migration Checklist Tutorial (2026): Move a Website to a New VPS Without Downtime

A good migration feels uneventful. Document what’s running. Reduce DNS risk. Copy files and databases carefully. Validate SSL and email. Keep a clear rollback path.

This hosting migration checklist tutorial gives you a repeatable process for moving sites to a VPS or dedicated server. It avoids the “we’ll fix it if it breaks” approach.

These steps assume you’re moving one or more websites from an old host to a new Linux VPS (or dedicated server), and you control DNS.

Where the approach changes for WordPress, cPanel, or a custom Nginx stack, it’s called out.

What you’ll migrate (and what people forget)

Before you touch the new server, inventory what actually makes the site work.

Most “mystery” failures come from skipping one of these items:

  • Web: Nginx/Apache/LiteSpeed config, vhosts, redirects, rewrites, HTTP/2/3 settings
  • App: PHP version + extensions, Node/Python runtime, environment variables, cron jobs
  • Data: site files (uploads), configuration files (.env/wp-config.php), any local storage
  • DNS: A/AAAA, CNAME, MX, TXT (SPF/DKIM/DMARC), SRV records if used
  • SSL: Let’s Encrypt automation, cert/key locations, intermediate chain
  • Email (if hosted on the same server): mailboxes, forwarders, filters, outbound reputation (PTR/rDNS)
  • Observability: log locations, error reporting, uptime checks, alerting endpoints

If you’re migrating customer sites (agency/reseller), treat this as change control.

Write down what changes, when it changes, and how you reverse it.

Step 1: Pre-migration freeze, backups, and TTL changes

Start 24–48 hours before cutover.

Your goal is simple: reduce the blast radius.

1) Lower DNS TTL for the records you’ll change

Lower TTL so the final DNS switch propagates quickly. A common target is 300 seconds.

Do this for the primary A/AAAA record and any “www” record you plan to change.

  1. Log in to your DNS provider.
  2. Edit A/AAAA and relevant CNAMEs.
  3. Set TTL to 300.
  4. Wait at least the old TTL period before cutover.

If you’ve dealt with stale resolvers or the wrong cached IP, use the diagnostics in DNS propagation troubleshooting tutorial.

2) Take a restorable backup (not just a copy)

A downloaded directory isn’t a plan. You need at least one backup you can restore quickly.

You also want a portable copy you control.

On the old server, a basic file backup looks like:

sudo tar -C /var/www -czf /root/site-files-$(date +%F).tar.gz example.com

For WordPress, include wp-config.php and uploads, plus a database export.

If you’re on cPanel, consider generating a full account backup in WHM/cPanel. It’s often the cleanest rollback.

3) Decide on a short “content freeze” window

If the site changes constantly (WooCommerce orders, membership activity, form submissions), plan a freeze window.

Even 10–20 minutes can prevent messy data drift.

  • Enable “maintenance mode” at cutover time.
  • Pause background jobs/cron that write data.
  • Hold inbound mail delivery changes until web cutover is stable.

If you need near-zero downtime WordPress with sync and a final delta, use WordPress migration tutorial as a companion.

Step 2: Prepare the new VPS like a production server

Provision the new box first, then migrate.

Doing both at once usually creates a long night of debugging.

Common culprits are SSH access, firewall rules, PHP config, and DNS changes happening in parallel.

If you want a straightforward base you can harden and tune, start with a HostMyCode VPS.

If you don’t want to manage OS updates, control panel updates, and backups yourself, managed VPS hosting is a better fit for business-critical sites.

1) Update OS packages and set the hostname

# Ubuntu/Debian
sudo apt update
sudo apt -y upgrade
sudo hostnamectl set-hostname newserver.example.com

2) Create a sudo user and lock down SSH basics

At minimum, use key-based SSH. Disable root password login.

Keep a known-good way back in if your first session drops.

Use your existing runbook, or follow SSH key setup guide for a safe baseline.

3) Apply a firewall rule set that won’t break the cutover

Open only what you need: 22/tcp (or your SSH port), 80/tcp, 443/tcp.

Add mail ports only if you actually host mail on this server.

Use the verification approach in firewall audit tutorial to confirm what’s exposed.

4) Install the web stack you intend to run

Pick one primary path and stick with it during cutover.

Avoid “stack changes” and “server move” at the same time.

  • cPanel/WHM (resellers and multi-tenant hosting): fastest account restores and predictable workflows.
  • Nginx + PHP-FPM (single or few sites, performance control): fewer moving parts if you’re comfortable with Linux.
  • Plesk/DirectAdmin (alternative control panels): fine, but keep the migration steps panel-specific.

If you’re migrating a traditional LAMP/LNMP server without cPanel, follow the structure in Web server migration tutorial.

Step 3: Copy site data safely (rsync over SSH)

Use rsync. It resumes cleanly.

It also supports a quick final “delta sync” right before cutover.

1) Create the destination directory

sudo mkdir -p /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com

2) Run the initial rsync (big copy)

From the new server, pull from the old server. That’s usually easier to firewall and audit.

sudo rsync -aHAX --numeric-ids --info=progress2 \
  -e "ssh -i /root/.ssh/migrate_key" \
  root@OLD_SERVER_IP:/var/www/example.com/ /var/www/example.com/

Pitfall: On shared hosting you may not have root.

Copy via SFTP/rsync as your account user. Then verify ownership and permissions after the transfer.

3) Exclude caches and bulky temp files

Cache directories regenerate and can waste time. Example for WordPress:

sudo rsync -aHAX --numeric-ids --delete \
  --exclude 'wp-content/cache/' \
  --exclude 'wp-content/uploads/cache/' \
  -e "ssh -i /root/.ssh/migrate_key" \
  root@OLD_SERVER_IP:/var/www/example.com/ /var/www/example.com/

Step 4: Move the database (and avoid encoding surprises)

Keep the database move boring.

Aim for correctness first, then speed.

1) Export on the old server

mysqldump --single-transaction --quick --routines --triggers \
  -u DBUSER -p'DBPASSWORD' DBNAME \
  | gzip > /root/db-$(date +%F).sql.gz

2) Transfer and import on the new server

scp /root/db-*.sql.gz root@NEW_SERVER_IP:/root/

gunzip -c /root/db-*.sql.gz | mysql -u DBUSER -p'DBPASSWORD' DBNAME

3) Quick verification queries

Run a fast sanity check before you touch DNS:

mysql -u DBUSER -p'DBPASSWORD' -e "USE DBNAME; SHOW TABLES;" | head

Pitfall: The app may expect a different database host or socket path on the new server.

Update the app config before testing (for WordPress: wp-config.php).

Step 5: Recreate web server vhosts and test with a hosts-file override

Don’t switch DNS just to test.

Prove the new server works privately first.

1) Point your laptop to the new server IP (temporary)

On macOS/Linux, edit /etc/hosts. On Windows, edit C:\Windows\System32\drivers\etc\hosts.

NEW_SERVER_IP   example.com www.example.com

Now only your machine resolves the domain to the new server. Everyone else still uses the old host.

2) Configure the vhost

Example Nginx server block path on Ubuntu:

  • /etc/nginx/sites-available/example.com
  • symlink to /etc/nginx/sites-enabled/
server {
  listen 80;
  server_name example.com www.example.com;

  root /var/www/example.com/public;
  index index.php index.html;

  access_log /var/log/nginx/example.com.access.log;
  error_log  /var/log/nginx/example.com.error.log;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
  }
}
sudo nginx -t
sudo systemctl reload nginx

WordPress note: If you plan to add caching or a reverse proxy later, get the site correct first.

Do performance tuning as a second pass. For a safe post-migration upgrade, use Nginx caching tutorial.

Step 6: SSL on the new server (before DNS cutover)

SSL is where migrations often stall.

The usual causes are bad chains, broken redirects, or ACME challenges that never validate.

Treat SSL as its own checkpoint.

Option A: Use a temporary validation method (recommended)

If your DNS provider supports DNS-based validation, you can issue certificates before you flip the A record.

That keeps cutover cleaner.

Option B: Issue after cutover and keep it fast

If you can’t use DNS validation, issue immediately after you switch DNS.

Keeping TTL low reduces the time you’re serving mixed traffic.

Follow the process in SSL Certificate Deployment Tutorial (2026). If renewals fail later, keep TLS renewal troubleshooting handy.

Step 7: Email and DNS records (don’t break deliverability)

If the old host handled email, decide whether email stays there or moves with the website.

Splitting web and mail is common and fine, as long as DNS matches what you’re actually doing.

1) If email stays on the old provider

  • Do not change MX records.
  • Keep SPF/DKIM/DMARC aligned with the sending service.
  • Only change A/AAAA for the website.

2) If email moves to the new server

Move mail in a separate window if you can.

If you can’t, set up authentication before you send anything.

Practical rule: Don’t start sending mail from a new IP without rDNS and SPF/DKIM/DMARC.

Otherwise, you can spend days digging out of spam folders.

Step 8: Final sync, cutover, and verification loop

This is the part you schedule.

Keep it short, written down, and easy to run under pressure.

Cutover runbook (copy/paste checklist)

  1. Announce freeze (maintenance mode / stop writes).
  2. Run final rsync with --delete to match old → new.
  3. Run final DB export/import (or delta approach if you prepared it).
  4. Disable background tasks on old server (cron, queue workers).
  5. Switch DNS A/AAAA to the new server IP.
  6. Issue/verify SSL and force HTTPS redirects.
  7. Verify key pages, login, forms, checkout, APIs.
  8. Watch logs for 30–60 minutes and fix 404/500s quickly.
  9. Remove maintenance mode.

Commands for the final rsync

sudo rsync -aHAX --numeric-ids --delete --info=progress2 \
  -e "ssh -i /root/.ssh/migrate_key" \
  root@OLD_SERVER_IP:/var/www/example.com/ /var/www/example.com/

Fast verification checklist (10 minutes)

  • HTTP status: home page returns 200, not 301 loops or 500.
  • Admin login: WordPress/wp-admin or your app auth works.
  • Forms: test contact form and any transactional email.
  • Static assets: CSS/JS load; no mixed-content warnings.
  • Uploads: open a media file and a recently uploaded image.
  • Logs: tail errors while you click around.

Useful log commands on the new server:

sudo tail -n 200 /var/log/nginx/example.com.error.log
sudo tail -n 200 /var/log/nginx/example.com.access.log
sudo journalctl -u php8.3-fpm --since "10 min ago"

Step 9: Rollback plan (the part you hope not to use)

A rollback is another cutover in reverse.

If you can’t describe it in three steps, it isn’t ready.

  • DNS rollback: switch A/AAAA back to the old IP (TTL should still be low).
  • Service rollback: re-enable old cron/workers and remove maintenance mode.
  • Data reconciliation: if any writes happened on the new server, decide what you keep.

Snapshots make rollback fast.

On high-traffic business sites, test snapshot restores ahead of time.

Don’t wait for an incident to learn the restore workflow.

Step 10: Post-migration cleanup and hardening

Once traffic is stable, tighten things up.

Save bigger changes for after the cutover window.

1) Restore DNS TTL to normal

After you’re confident (often 24 hours), raise TTL back to something reasonable like 3600–14400 seconds.

2) Remove old server exposure

  • Disable public web access on the old host (or firewall it to your IP only).
  • Keep it available for a short period if you need to fetch missing files.
  • Then decommission to avoid “ghost servers” with unpatched software.

3) Add performance improvements carefully

If you didn’t change the stack, you can still pick up speed with safe compression and caching.

For Nginx, add microcaching only after you confirm login and cart behavior.

The rules and purge methods are covered in the Nginx caching tutorial (2026).

4) Monitor for the “day two” problems

Many migration issues show up later.

Cron may not run. Mail may land in spam. Renewals may fail. Disks can fill from logs.

Want a predictable migration target with full root access? Run the new environment on a HostMyCode VPS. If you’d rather hand off updates, backups, and security baselines for production sites, choose managed VPS hosting and keep your team focused on the application.

FAQ: Hosting migration checklist tutorial

How long should I keep the old server after cutover?

Keep it for at least 7 days for low-risk sites, longer if you need audit logs or you expect delayed DNS resolvers.

Firewall it down so it doesn’t turn into a forgotten attack surface.

Should I migrate web and email in the same window?

Only if you have no choice.

Web first, then email is safer.

Email deliverability hinges on DNS auth and rDNS. Mistakes there can take a while to unwind.

What’s the safest way to test the new server without switching DNS?

Use a hosts-file override on your workstation and test the real domain against the new IP.

That validates cookies, redirects, and absolute URLs.

My SSL won’t issue after the move. What should I check first?

Confirm the domain resolves to the new IP from public resolvers, and make sure ports 80/443 are reachable.

Then check that your ACME challenge path isn’t blocked by redirects or auth rules.

Summary: a migration process you can repeat

The migrations that go well are the quiet ones.

You lower TTL, take a real backup, prep the new server, sync files and data, test with a hosts override, then switch DNS with a rollback plan ready.

If you want a clean new home with room to scale, start on a HostMyCode VPS and treat every move as a documented change—not an experiment.