IPv4 & IPv6 Leasing - Any RIR, Any LocationOrder Now
Hostperl

Managed Hosting Cutover on Debian Without Downtime

By Raman Kumar

Share:

Updated on Oct 26, 2026

Managed Hosting Cutover on Debian Without Downtime

What this cutover solves

Use this guide when you need to move a customer site, reseller account, or managed server service from one Debian 12/13 VPS to another with the least possible interruption. The goal is not just to copy files. You will prepare DNS, create a non-root administrator, sync content safely, validate the new host, and keep a rollback path open until the cutover is confirmed.

This is a practical fit for agency workflows, regional hosting moves, and support-led migrations on Hostperl VPS where you need clean handover, predictable maintenance windows, and a fast recovery path if something does not behave as expected.

Before you start

This procedure assumes:

  • Debian 12 or Debian 13 on both servers.
  • Root SSH access on the old and new servers.
  • A domain name already pointing to the old server.
  • Enough disk space on the new server for a full sync.
  • rsync installed on both ends.

If your current service is managed through a panel, review WHM account operations that keep hosting moves clean and cPanel WHM license recovery for hosting moves if the move also includes licensing or control-panel changes. The file-sync and DNS principles here still apply.

1) Connect to the source server and identify the OS

On your local computer, open your first SSH session to the source server. Replace 203.0.113.10 with the real public IP assigned by your provider.

ssh root@203.0.113.10

Keep this root session open. You will use it as your safety net while you prepare the new server.

On the VPS as root, confirm the operating system before you touch packages or firewall rules.

cat /etc/os-release

You should see Debian 12 or Debian 13 in the output. If you are not on Debian, stop here and follow a distribution-specific migration path instead.

2) Create a non-root admin on the new server

On your local computer, open a second terminal and connect to the new server.

ssh root@203.0.113.10

Again, replace the documentation IP with the actual new server IP. Now set up your admin account before you make any access changes.

On the VPS as root, create the account, grant sudo access, and prepare SSH keys. Use the same account name Hostperl support teams often use in handovers: deploy.

adduser deploy

Follow the prompts to set a password for the new account. Then add it to the sudo group.

usermod -aG sudo deploy

Create the SSH directory and lock down ownership and permissions.

install -d -m 700 -o deploy -g deploy /home/deploy/.ssh

Copy your public key into place. Replace the sample key text with your real key.

cat > /home/deploy/.ssh/authorized_keys <<'EOF'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMyExampleKeyReplaceWithYourOwnKey comment
EOF

Set restrictive permissions so SSH accepts the file.

chown deploy:deploy /home/deploy/.ssh/authorized_keys
chmod 600 /home/deploy/.ssh/authorized_keys

Confirm the account is ready.

ls -ld /home/deploy /home/deploy/.ssh
ls -l /home/deploy/.ssh/authorized_keys

You should see deploy as the owner and tight permissions on the SSH directory and key file.

3) Update packages and time sync

On the VPS as root, refresh package metadata and apply current security updates before the migration work begins.

apt update
apt -y upgrade

Install the tools you need for the move.

apt -y install rsync curl chrony

Enable time sync so file timestamps and TLS validation behave properly during cutover.

systemctl enable --now chrony

Check that the service is active.

systemctl status chrony --no-pager

You should see active (running). If the service fails, inspect the journal before proceeding.

journalctl -u chrony -n 50 --no-pager

4) Prepare the destination layout

On the VPS as root, create the target directory structure. This example uses /opt/myapp as a generic application path because you may be moving a web app, customer portal, or support tool.

mkdir -p /opt/myapp/{current,backup,shared}
chown -R deploy:deploy /opt/myapp

Check that the directories are present and owned by the admin user.

ls -ld /opt/myapp /opt/myapp/*

If your service is static or proxied, a clean directory layout makes rollback much simpler.

5) Sync the live data with rsync

On the VPS as root, copy the current live data from the old server to the new one. Replace the source path with the real application or site path on the source host.

rsync -aHAX --numeric-ids --delete --info=progress2 root@203.0.113.10:/var/www/example/ /opt/myapp/current/

This command preserves permissions, ACLs, extended attributes, and ownership. It also removes files on the new server that no longer exist on the source. That keeps the destination consistent with production.

Run a dry check after the first sync to catch obvious mismatches.

rsync -aHAX --numeric-ids --delete --dry-run root@203.0.113.10:/var/www/example/ /opt/myapp/current/

If the dry run shows large unexpected deletes or missing directories, stop and inspect the source path before continuing.

6) Add a firewall before exposing the new server

On the VPS as root, install and enable UFW on Debian if it is not already present.

apt -y install ufw
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable

This opens SSH, HTTP, and HTTPS before you point live traffic at the new host. Do not remove the old server from service until you can confirm the new one answers correctly.

Verify the firewall state.

ufw status verbose

You should see the three allowed services and an active firewall.

7) Set up Nginx as the new front end

For a managed hosting cutover, Nginx is often the cleanest front end because it can serve static files, reverse proxy app traffic, and give you clear logs for support. If your existing stack uses Apache, keep that unchanged unless the migration specifically includes a web server change. This tutorial stays focused on the cutover itself, not a web-server comparison.

On the VPS as root, install Nginx.

apt -y install nginx

Create a site configuration for the migrated service.

cat > /etc/nginx/sites-available/example.com <<'EOF'
server {
    listen 80;
    server_name example.com www.example.com;

    root /opt/myapp/current/public;
    index index.html index.php;

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

    location / {
        try_files $uri $uri/ /index.html;
    }
}
EOF

Enable the site and disable the default if you do not want it answering requests.

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
rm -f /etc/nginx/sites-enabled/default

Test the configuration before any reload.

nginx -t

A successful test ends with syntax is ok and test is successful. Then reload Nginx.

systemctl reload nginx

Check the service status.

systemctl status nginx --no-pager

If Nginx refuses to start, inspect the syntax and logs first, not the firewall.

journalctl -u nginx -n 50 --no-pager

8) Move SSL into place

Once the DNS cutover is ready, obtain a certificate with Let's Encrypt. You can do this before the final switch if the DNS record already points to the new host, or after you lower the TTL and are ready to flip traffic.

On the VPS as root, install Certbot and request a certificate for the live name.

apt -y install certbot python3-certbot-nginx
certbot --nginx -d example.com -d www.example.com

Certbot will update the Nginx server block automatically. Re-test afterward.

nginx -t
systemctl reload nginx

For customers moving regional services, this is a useful point to review DNS and nameserver handling with the 2026 hosting buyer decision framework for real buyers and keep DNS changes predictable rather than rushed.

9) Lower DNS TTL before the cutover

On your DNS provider's control panel, reduce the A and AAAA record TTL for example.com and www.example.com to 300 seconds at least a few hours before the switch. This shortens propagation time and reduces the number of stale resolvers still pointing to the old server.

If you manage DNS through Hostperl services, the DNS and domain workflow usually becomes easier to coordinate during a migration. See Hostperl IP rental and DNS services if your move also involves a new address or region.

10) Do the final sync and freeze writes

On the source server, stop write-heavy services first. That may be your app worker, queue consumer, or database write path. The idea is to prevent a moving target during the last copy.

Then run a final rsync from the old host to the new host.

rsync -aHAX --numeric-ids --delete --info=progress2 root@203.0.113.10:/var/www/example/ /opt/myapp/current/

If the app stores uploads or customer-generated files separately, copy those paths too. Keep the old server running until the new one answers correctly.

11) Check ownership, logs, and service health

On the VPS as root, confirm file ownership after the final sync.

find /opt/myapp/current -maxdepth 2 -printf '%u:%g %p
' | head

Then review Nginx logs for a live request.

tail -n 20 /var/log/nginx/example.com.access.log
tail -n 20 /var/log/nginx/example.com.error.log

If your application needs a systemd service, enable and check it now. Replace myapp with your real service name.

systemctl enable myapp
systemctl status myapp --no-pager

For app-service troubleshooting patterns, Nginx access logs for supportable app hosting is a useful companion reference.

12) Verify from the server and a client

On the VPS as root, check that Nginx is listening on the expected ports.

ss -tulpn | grep -E ':(80|443)\s'

Then confirm the local HTTP response.

curl -I http://127.0.0.1

You should see an HTTP 200, 301, or 302 depending on your redirect setup.

On your local computer, test the live domain once DNS begins to point to the new host.

curl -I https://example.com

Run a functional smoke test too. For example, load the login page, submit a simple form, or open the customer dashboard. A green HTTP code alone is not enough for managed hosting work.

Rollback plan if the cutover fails

If the new server shows broken assets, login errors, or missing data, switch DNS back to the old server immediately. Because you lowered TTL earlier, the rollback should propagate faster than the original move.

On the old server, keep the source copy intact until the new host has run cleanly for at least one business cycle. If you must revert application data, reverse the rsync direction only after you confirm which side contains the correct writes.

rsync -aHAX --numeric-ids --delete --info=progress2 /var/www/example/ root@203.0.113.10:/var/www/example/

Use this only when you are certain the source of truth is back on the old host. Reversing the wrong way can overwrite fresh customer data.

Troubleshooting the most common failures

SSH key rejected

Run this on the new server.

ls -ld /home/deploy /home/deploy/.ssh
ls -l /home/deploy/.ssh/authorized_keys

If permissions are too open or ownership is wrong, fix them with:

chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys

Nginx returns 403

Check whether the document root exists and whether the web user can read it.

ls -ld /opt/myapp/current /opt/myapp/current/public
namei -l /opt/myapp/current/public

Correct the path or permissions if the web root is missing.

Certificate issuance fails

Check DNS resolution and port 80 access.

dig +short example.com
ufw status verbose
curl -I http://example.com

If port 80 is closed or the domain still points at the old server, fix DNS first, then rerun Certbot.

Old data still appears after the move

That usually means cached DNS, browser cache, or an upstream proxy. Confirm the target server is receiving traffic.

tail -f /var/log/nginx/example.com.access.log

If no requests appear, the client is still reaching the old host or a cache layer is in front of the new one.

Reboot persistence check

On the VPS as root, confirm that the services come back after reboot.

systemctl is-enabled nginx
systemctl is-enabled chrony
systemctl is-enabled myapp

If all three show enabled, schedule a maintenance reboot only after the migration has been stable.

reboot

After the server returns, reconnect and re-run:

systemctl status nginx chrony myapp --no-pager
ss -tulpn | grep -E ':(80|443)\s'

That final check confirms the cutover survived a restart, which is what customers will experience later during routine maintenance.

If you need help moving a customer site, reseller account, or managed service without a rushed DNS window, Hostperl can help you plan the handoff and keep rollback options open. For migration-friendly infrastructure, start with Hostperl VPS hosting or a dedicated server hosting plan when the workload needs more predictable resources.

Our support team is used to real migration windows, not just green checkmarks. That matters when you are coordinating customers, email delivery, and live traffic at the same time.

FAQ

How long should I keep the old server online?

Keep it online until DNS has fully propagated and the new server has handled live traffic cleanly for at least 24 to 48 hours.

Should I switch DNS before or after the final rsync?

Do the final rsync first, then switch DNS. That reduces the chance of users landing on a partially synced destination.

Can I skip lowering TTL?

You can, but rollback becomes slower. Lowering TTL is a small step that saves time if the new server needs to be withdrawn.

What if my app uses a database?

Freeze writes, take a final database backup or dump, move the database separately, and verify the app connects before you point traffic at the new host.

Is this process suitable for agency clients?

Yes. It works well for agencies because it preserves a clear rollback path and keeps the client-facing cutover controlled.