How to Migrate a Website or App to a New Cloud Server
To migrate to a cloud server safely, leave the old machine untouched until the new one has served real traffic. This guide is a plan you can follow for a website, a shop or an application: three checklists (before, cutover, rollback), commands you can adapt, and honest limits on downtime. Size the target first with the cloud server sizing guide and choose the region with the European location guide.
Pick the migration method
Four methods cover almost every move. Many projects combine two of them.
| Method | Best for | Main risk |
|---|---|---|
| rsync of files | Static sites, uploads, app code | Data changes during the copy, so a final sync is needed |
| Image or backup restore | Same OS and layout, a tested restore | Old drivers and network names, a larger transfer |
| App redeploy | Containers and code in git | Hidden state on the old disk is forgotten |
| Database replication | Large or busy databases | Setup effort and version limits |
Start from a cloud server from EUR 15.00/mo, checked 2026-10 and rehearse the whole plan there.
Pre-migration checklist
- Inventory - list services, ports, cron jobs, mail settings, certificates, firewall rules and every hostname that points to the old IP.
- Hidden state - find files outside the web root: uploads, queues, sessions, license files, secrets in environment variables.
- Backups - take a full backup of the old server and restore it once somewhere, because an untested backup is only a hope.
- Access - SSH keys only, a firewall, and a non-root deploy user on the new server.
- Snapshot - take a snapshot of the new server before the first real sync, so a mistake costs minutes.
Copy files and data
The samples use the documentation address 203.0.113.10 as the new server. Replace names and paths with yours. Steps 1 and 2 can be repeated safely, step 5 runs only once the old site is read-only.
# 1. Bulk copy while the old server keeps serving (repeat any time)
rsync -aHAX --numeric-ids --info=progress2 \
-e ssh /var/www/ deploy@203.0.113.10:/var/www/
# 2. Database dump and restore (MySQL / MariaDB shown)
mysqldump --single-transaction --routines --triggers appdb \
| gzip | ssh deploy@203.0.113.10 'gunzip | mysql appdb'
# 3. Test the new server under the real hostname, DNS untouched
curl -sS --resolve example.com:443:203.0.113.10 \
https://example.com/ -o /dev/null -w '%{http_code}\n'
# 4. Check the TTL resolvers will honour
dig +noall +answer example.com A
# 5. Final sync after the old site is read-only
rsync -aHAX --numeric-ids --delete \
-e ssh /var/www/ deploy@203.0.113.10:/var/www/
The --delete flag removes files on the target that no longer exist on the source. Use it only in the final run, and only when you are sure which side is the master.
Test with a hosts file first
Before DNS changes, make your own computer resolve the site to the new server. Add one line to the hosts file (/etc/hosts, or C:\Windows\System32\drivers\etc\hosts on Windows): 203.0.113.10 example.com www.example.com. The curl --resolve option in step 3 does the same for a single request. Remove the hosts line afterwards, or you will test the new server for weeks without noticing.
Lower the DNS TTL and cut over
Lower the TTL of the A and AAAA records to about 300 seconds at least one full old-TTL period before the move. Otherwise resolvers keep the old address as long as the old TTL says. Some resolvers ignore a short TTL, so expect a tail of visitors on the old IP for hours (an estimate, not a measurement).
Cutover checklist:
- TTL - the lowered value is live and the old one has expired.
- Read-only - the old site is in maintenance or read-only mode.
- Final sync - last database dump and step 5 from the code above are done.
- DNS - A and AAAA records point to the new IP; mail records are unchanged unless mail moves too.
- Smoke test - login, order, upload, e-mail, cron and the certificate are checked on the public name.
- Old server - keep it running, reachable and untouched.
Rollback checklist
- Threshold - decide in advance what counts as failure, for example failed payments or a 5xx rate, and who decides.
- DNS back - point the records to the old IP; with a low TTL most visitors return within minutes to hours.
- Writes - reopen the old site. If the new one accepted orders or uploads since the cutover, export them first and replay them on the old side.
What zero downtime really needs
Zero downtime depends on the architecture of your application and is not promised for any project. It needs a stateless app, a database that can replicate or accept writes on both sides, shared or replicated storage, and a tested switch. A classic site with one database usually has a short read-only window of minutes instead.
After the move
Watch error logs, disk, memory, response times and mail delivery for at least a week. Raise the DNS TTL again once things are stable. Decommission the old server only after a full backup cycle has passed on the new one; a weekly backup is included with each preset. Use the trial checklist to test before you commit; a short trial may be possible by writing to sales@dcxv.com, at DCXV discretion and not guaranteed.
Configure the destination cloud server, or ask an engineer about migration.
