Virteche
Guideschevron_rightServers

Servers · 10 min read · Updated

How to Move a Website to a New Server with Almost No Downtime

Moving a website to a new server takes five steps: build the new server alongside the old one, copy the files and database across, test the new copy before anyone else sees it, copy the last changes, then switch DNS. Because the old server keeps running until the switch, visitors see little or no downtime: none for a static site, a few minutes for one with a database. The steps are the same whether you are leaving DigitalOcean, Linode, Vultr, Hetzner, AWS Lightsail or a shared host.

1. Write Down What the Old Server Does

A move goes wrong because of the thing nobody remembered. On the old server, list:

cat /etc/os-release                   # OS and version
ls /etc/nginx/sites-enabled /etc/apache2/sites-enabled 2>/dev/null
crontab -l; sudo crontab -l           # scheduled jobs
systemctl list-units --type=service --state=running
sudo ss -tlnp                         # what is listening, on which ports
du -sh /var/www                       # how much there is to copy

Also note where the site keeps uploads, which database it uses, any .env or config files with passwords and API keys, and every DNS record for the domain.

2. Lower the DNS TTL a Day Ahead

The TTL is how long resolvers cache your records. At your DNS provider, set it to 300 seconds (5 minutes) on the records you will change, then wait at least as long as the old TTL, often an hour and sometimes a day. After that, the switch reaches almost everyone within five minutes.

3. Set Up the New Server

Install the same software the old server runs, ideally the same major versions of PHP, Node.js, Python or the database. If you are starting fresh, these guides cover the usual setup: first steps on a new server, Nginx and HTTPS, and Docker if your site runs in containers. If it does, copying the Compose file and the volumes is most of the move.

4. Copy the Files

Run rsync on the new server and pull from the old one. It needs SSH access to the old server (add the new server's key there, or use a password just for the move):

rsync -aHAX --numeric-ids --info=progress2 \
  root@OLD_SERVER_IP:/var/www/ /var/www/

The trailing slashes matter: they copy the folder's contents into the folder of the same name. Copy the web server config and certificates the same way, then adjust anything that mentions the old IP address:

rsync -a root@OLD_SERVER_IP:/etc/nginx/sites-available/ /etc/nginx/sites-available/
rsync -a root@OLD_SERVER_IP:/etc/letsencrypt/ /etc/letsencrypt/

Copying /etc/letsencrypt whole keeps the certificates and their renewal settings, so HTTPS works before DNS points at the new server. Install certbot on the new server so renewals carry on, and enable each site (the symlinks in sites-enabled) once its paths are right.

5. Copy the Database

Create the database and its user on the new server first, with the same names and password as the old one so the app's config needs no change. Then stream a dump straight across. MySQL and MariaDB:

ssh root@OLD_SERVER_IP "mysqldump --single-transaction --routines --triggers --events mydb" \
  | mysql mydb

PostgreSQL:

ssh root@OLD_SERVER_IP "sudo -u postgres pg_dump -Fc mydb" > mydb.dump
sudo -u postgres pg_restore --no-owner --role=myapp -d mydb < mydb.dump

--single-transaction gives a consistent copy of InnoDB tables without locking the live site.

6. Test Before DNS Changes

Point only your own computer at the new server by adding a line to your hosts file (/etc/hosts on macOS and Linux, C:\Windows\System32\drivers\etc\hosts on Windows, edited as administrator):

NEW_SERVER_IP  example.com www.example.com

Browse the site, sign in, submit a form, upload a file, and watch the logs on the new server while you do (sudo tail -f /var/log/nginx/error.log). Remove the line when you are done.

7. Switch Over

  1. Stop writes on the old server: put the site in maintenance mode or stop the app, so no new orders or comments land there.
  2. Run the rsync and database copy from steps 4 and 5 again. Only the changes are sent, so it is quick.
  3. Change the A record (and AAAA, if you use IPv6) for the domain and www to the new server's address.
  4. Start the app on the new server and watch its access log fill up as DNS changes over.

Recreate the cron jobs and background services from your list in step 1. They are the part most often forgotten.

8. Keep the Old Server for a Few Days

A few resolvers ignore short TTLs, so some traffic reaches the old server for a while. Leave it running (in maintenance mode) for a few days, and set up backups on the new server before you cancel the old one. How to back up a Linux server with Borg covers that.

Common Questions

  • Does it matter which provider I am moving from?

    Not for these steps. DigitalOcean, Linode, Vultr, Hetzner, AWS Lightsail and a server under your desk all give you a Linux machine you can reach over SSH, which is all this needs. Shared hosting without SSH works too: download the files over SFTP or the control panel's file manager, and the database with phpMyAdmin's export.

  • How long will the site be down?

    A static site: not at all, because both servers can serve it while DNS changes over. A site with a database: only the few minutes between stopping writes on the old server and the new one taking over, for the final copy of changes.

  • Can I keep my email where it is?

    Yes. Only change the records for the website (usually the A and AAAA records for the domain and www). Leave MX and the email-related TXT records as they are, and your mail is not affected.

  • My app sends email. Will that still work?

    Send it through your email provider on port 587 or 465. On Virteche Cloud, outgoing connections on port 25 are blocked, which keeps our addresses off spam blocklists.

KVM servers in Ashburn and Dallas with a dedicated IPv4 address. Build the new one next to your old server and switch when you are ready.

See VPS plans

Keep Reading

All guides
How to Move a Website to a New Server | Virteche Cloud