Migrate a Website to a New VPS: rsync and a DB Dump
Moving a site to a new server comes down to three things: copy the files, transfer the database and switch the domain. If you do them in order and test the site before changing DNS, the migration happens with almost no downtime.
The migration plan
- Prepare the new VPS (web server, PHP, database).
- Copy the site files with
rsync. - Transfer the database as a dump.
- Test the site on the new server by IP.
- Switch DNS and wait for propagation.
Step 1. Prepare the new server
Install the same environment as on the old machine (LEMP, for example) and create an empty database and a user. Set up SSH access between the servers — the easiest way is to generate a key on the old one and add it to the new one:
ssh-keygen -t ed25519
ssh-copy-id user@NEW_SERVER_IP
Step 2. Copy the files with rsync
rsync transfers only the changed files and preserves permissions. Run it from the old server:
rsync -avz --progress /var/www/example.com/ \
user@NEW_SERVER_IP:/var/www/example.com/
The flags: -a preserves permissions, owners and symlinks, -z compresses the transfer, -v prints details. A trailing slash on the source means “the contents of the directory”.
For a large site, run a preliminary sync in advance and the final one right before the switch, so it catches up on the recent changes.
Step 3. Transfer the database
Create a dump on the old server. For MySQL/MariaDB:
mysqldump --single-transaction -u root -p app_db | gzip > app_db.sql.gz
Copy the dump to the new server:
rsync -avz app_db.sql.gz user@NEW_SERVER_IP:/tmp/
Import it on the new server:
gunzip < /tmp/app_db.sql.gz | mysql -u root -p app_db
For PostgreSQL the commands are similar:
pg_dump -Fc app_db > app_db.dump
# on the new server:
pg_restore -d app_db --clean app_db.dump
Step 4. Update the site configuration
Update the database connection string in the application config (wp-config.php, .env and so on) — host, database name, user, password. Check the directory permissions:
sudo chown -R www-data:www-data /var/www/example.com
Step 5. Test before the DNS switch
Without touching DNS, test the site on the new server by overriding the domain in the hosts file on your own computer:
NEW_SERVER_IP example.com
(On Linux and macOS this is /etc/hosts.) Open the site — if everything works, you can switch the domain. Remove the line from hosts afterwards.
Step 6. Switch DNS
Lower the TTL of the A record in advance (to 300 seconds, for example) a day before the move — the switch then propagates faster. Change the A record to the new server IP and watch it:
dig +short example.com
While DNS is updating across providers, part of the traffic still goes to the old server — so keep it running for at least a day.
Post-migration checklist
| Check | How |
|---|---|
| The site opens | by domain after the DNS change |
| The database is connected | no connection errors in the logs |
| File permissions | chown www-data, uploads work |
| SSL | reissue with certbot on the new server |
| Cron jobs | move the crontab manually |
FAQ
How do I move a site without downtime?
Sync the files and the database in advance, test the site through hosts, then run a final sync and switch DNS. Keep the old server running for a day.
Why does rsync not preserve permissions?
Run it with the -a flag (archive mode) and as a user with sufficient rights; preserving owners in full may require sudo and --numeric-ids.
Do I have to move the SSL certificate? It is easier to reissue it with certbot on the new server after the DNS switch — that takes a minute.
Why do some visitors still see the old site after the move? DNS is cached by providers according to the TTL. Lower the TTL in advance and wait a few hours after changing the record.
For the new server, pick a configuration with some headroom: see VPS hosting, and for CMS-based sites there is WordPress VPS.