Moving a website (from shared hosting, another VPS, or another provider) to a new VPS doesn’t have to mean downtime. The trick is to build and test the new server first, then switch DNS with a short TTL, and do a final data sync at cutover. This guide works for most PHP, static and database-backed sites. WordPress specifics are covered in migrate WordPress to a VPS.
1. Inventory the old site
Write down:
- domains and subdomains, and where DNS is hosted;
- web server, language and versions (PHP 8.x, Node.js, Python…), and required extensions;
- databases (type, version, size, users);
- cron jobs and background workers;
- email: is mail hosted on the same server, or elsewhere (Google Workspace, Microsoft 365)?
- SSL certificates, and any special server config (redirects,
.htaccessrules).
2. Build the new VPS
- Choose the location near your users, and the OS. See choosing a VPS location.
- Secure it: SSH keys, firewall, Fail2ban. See Linux server hardening checklist.
- Install the stack with matching versions. See WordPress on Ubuntu with Nginx or install a LAMP stack.
- Create the site’s server block or virtual host, database and database user.
3. Copy files and databases
Files (from the old server, or over SSH from the new one):
rsync -avz --progress [email protected]:/home/olduser/public_html/ /var/www/example.com/
If the old host only offers FTP/SFTP or a control panel backup, download an archive, and upload it with scp or rsync. See rsync examples.
Database:
# on the old server (or via its panel / phpMyAdmin export)
mysqldump --single-transaction -u olduser -p olddb | gzip > db.sql.gz
# on the new server
gunzip -c db.sql.gz | mysql -u newuser -p newdb
Update the app’s config (database host, name, user and password, file paths). See mysqldump.
4. Test before touching DNS
Point the domain to the new server only on your computer, by editing your hosts file:
# /etc/hosts (macOS/Linux) or C:\Windows\System32\drivers\etc\hosts
203.0.113.10 example.com www.example.com
Then browse the site: pages, logins, forms, uploads, checkout, admin, and cron-driven features. For HTTPS testing before cutover, use a temporary self-signed certificate, or get a certificate after cutover (Certbot needs the real DNS). Or use DNS-01 validation to get a certificate early.
5. Lower the DNS TTL in advance
A day or two before the move, lower the TTL of the domain’s A/AAAA records (for example to 300 seconds), so the change propagates quickly. See DNS TTL and propagation.
6. Cutover
- Freeze changes on the old site if possible (maintenance mode, or pause orders and comments).
- Final sync: re-run rsync for files, and re-export and import the database, so the new server has the latest data.
- Switch DNS: update the A (and AAAA) records to the new VPS’s IP. See point a domain to a VPS.
- Issue SSL certificates on the new server:
sudo certbot --nginx -d example.com -d www.example.com. See Let’s Encrypt. - Watch logs on both servers. Traffic shifts to the new one as DNS caches expire.
7. Don’t break email
If email is hosted at the old provider, keep the MX records pointing there (only change A records for the website). If you move email too, migrate the mailboxes (imapsync), and update MX, SPF, DKIM and DMARC. See SPF, DKIM and DMARC.
8. After the move
- Re-create cron jobs on the new server, and disable them on the old one (to avoid double runs).
- Set up backups and monitoring on the new server. See Uptime Kuma.
- Keep the old server running for a few days, as a rollback option. Then cancel it.
- Raise the DNS TTL back to a normal value.
Rollback plan
If something goes wrong after cutover, point DNS back to the old IP (the short TTL makes this fast), and investigate. That’s why the old server stays untouched until the new one is proven.
Quick reference
| Step | Tool |
|---|---|
| Copy files | rsync -avz old:/path/ /var/www/site/ |
| Copy DB | mysqldump … | mysql … |
| Test privately | hosts file override |
| Fast switch | Lower TTL beforehand |
| SSL | Certbot after DNS points to the new server |
Related: upgrade from shared hosting to a VPS and VPS vs shared hosting.