# How to Migrate a Full Server from RunCloud to xCloud

> Move every WordPress site on a RunCloud NGINX or OpenLiteSpeed server to xCloud in one run with root SSH: eligibility, backups, demo copies, validation, DNS cutover, rollback.

This guide shows you how to move multiple WordPress sites from one eligible RunCloud-managed server to a fresh xCloud-provisioned server in one run. If you are still deciding, see [xCloud vs RunCloud](/xcloud-vs-runcloud/) first. It is for server owners who control the source VPS and can grant root SSH access. xCloud's full-server migration currently accepts supported NGINX and OpenLiteSpeed sources, and xCloud explicitly lists RunCloud OpenLiteSpeed as supported.

This process copies sites to xCloud before you change production DNS. It does not guarantee zero downtime. Plan a short write freeze for the final validation and cutover, and keep the RunCloud server available until the rollback window ends.

## Is full server migration the right method?

Use full-server migration only when every item in the **Eligible** column is true.

| Check | Eligible for this guide | Use a site-level migration instead |
|---|---|---|
| Workload | Multiple WordPress sites on one RunCloud server | A single WordPress site, or a non-WordPress application |
| Source stack | NGINX or OpenLiteSpeed | A stack not listed in xCloud's current prerequisites |
| Operating system | Ubuntu 20.04 or Ubuntu 24.04 LTS on x86-64 | Ubuntu 22.04, ARM/aarch64, or another operating system |
| Access | Root SSH access by password or public key | Root access is unavailable or prohibited |
| Destination | A fresh server provisioned through xCloud | An existing destination that cannot be replaced |

RunCloud supports a broader set of source configurations than xCloud's full-server migration currently lists. For example, RunCloud supports Ubuntu 22.04 and Ubuntu 24.04 on aarch64, but those configurations are outside xCloud's published full-server prerequisites. Do not proceed with this workflow unless the source matches both providers' requirements.

If the server is ineligible, migrate each WordPress site with [xCloud's WordPress migration workflow](/docs/migrate-an-existing-wordpress-website-in-xcloud/) instead.

## Prerequisites
- Owner or administrative access to the RunCloud server and its underlying cloud-provider account
- Root SSH access to the source server
- The source runs Ubuntu 20.04 or Ubuntu 24.04 LTS on x86-64
- The source uses NGINX or OpenLiteSpeed
- TCP port 22 is reachable from the internet during the migration
- Verified backups of every WordPress web application and database
- A fresh destination server provisioned through xCloud
- Enough destination storage for all selected sites, with at least 1 GB left free after the copy
- Access to the authoritative DNS zone for every production domain
- A maintenance window and rollback window agreed with site owners
- A list of active plugins, must-use plugins, caching layers, scheduled jobs, and external integrations for each site

## Step 1: Record the source configuration

In RunCloud, open the source server and record its operating system, architecture, web stack, public address, SSH port, and the WordPress applications you intend to move. Confirm the operating system and architecture directly on the server if the dashboard does not show both values.

**Expected result:** You have a migration inventory, and the operating system, architecture, web stack, and workload pass the eligibility table above.

## Step 2: Create and verify RunCloud backups

Create current web-application and database backups for every WordPress site. Use RunCloud's [backup creation guide](https://runcloud.io/docs/creating-backups), then confirm that each backup appears as completed. Review [RunCloud's restore procedure](https://runcloud.io/docs/restoring-runcloud-backups) before continuing so you know how to recover the source if needed.

A server-provider snapshot can add another rollback point, but it does not replace portable web-application and database backups.

**Expected result:** Every selected site has a recent, completed backup and a known restore path.

## Step 3: Prepare root SSH access in RunCloud

Open the source server in RunCloud, then go to **SSH**. RunCloud's [SSH configuration guide](https://runcloud.io/docs/configure-ssh-on-runcloud) documents the **SSH Key** and **Config** pages.

If **Prevent root login** is enabled, temporarily turn it off for the migration window. Keep **Passwordless login** enabled when you will use xCloud's public-key method. If you use password authentication, confirm that the root password works before entering it in xCloud. Ensure TCP port 22 is open in the source firewall and any cloud-provider firewall.

**Expected result:** A root SSH session can reach the source server using the authentication method you will select in xCloud.

## Step 4: Prepare the WordPress sites

Schedule the work before disabling protection. Following xCloud's current full-server prerequisites, clear application and object caches, disable cache and security plugins that may block the copy, and remove source-host must-use plugins that should not move to xCloud. Record every change so you can restore the source configuration during rollback.

Do not disable security controls earlier than necessary. Keep the migration window short and restrict SSH access at the firewall when your network policy supports it.

**Expected result:** The selected sites are backed up, their temporary changes are documented, and migration-blocking cache or security layers are inactive.

## Step 5: Provision a fresh destination server in xCloud

Create a new server through xCloud. Do not use an existing production destination for this workflow. Size its storage for the selected files and databases, plus growth and at least 1 GB of free space after migration.

Wait until xCloud marks the destination server as active before starting the copy.

**Expected result:** A fresh xCloud-provisioned destination server is active and has sufficient storage.

## Step 6: Open the full-server migration flow

In xCloud, open **Servers**, select the fresh destination server, and open **Migration**. Start the full-server migration flow described in [How to perform a full server migration with xCloud](/docs/perform-a-full-server-migration-with-xcloud/).

**Expected result:** xCloud displays the source-server connection form.

## Step 7: Connect xCloud to the RunCloud server

Enter the source server's public address, SSH port (normally `22`), and SSH username `root`.

Choose one authentication method:
- **Password:** Enter the current root password.
- **Public key:** Copy the public key shown by xCloud, add it to the source server's root account from RunCloud's **SSH Key** page or an existing root shell, then return to xCloud.

Continue only after xCloud accepts the connection. Never place a root password or private key in a ticket, document, or screenshot.

**Expected result:** xCloud connects to the source and discovers the WordPress sites available for migration.

## Step 8: Select the WordPress sites

Review the discovered sites and select only the sites included in your migration inventory. Confirm that each expected production domain appears before clicking **Next**.

If a site is missing, stop and verify that it is a WordPress site on the connected server, that its files and database are accessible to root, and that its stack is supported. Do not continue with an incomplete selection.

**Expected result:** The selection matches the approved site inventory exactly.

## Step 9: Create demo sites first

Choose the demo-site option rather than sending the sites live immediately. Start the migration and monitor it until xCloud reports completion.

Keep the RunCloud server online while xCloud copies data. Do not change DNS or resume disabled destination workers during this stage.

**Expected result:** xCloud creates non-production copies of the selected sites for validation.

## Step 10: Validate every migrated site

Test each demo site before cutover. Check:
- the homepage, key landing pages, forms, redirects, and media files;
- WordPress administrator login and a safe non-production content edit;
- recent posts, users, orders, comments, or other business data;
- plugin and theme behavior;
- scheduled actions and cron-dependent features;
- transactional email through the intended provider;
- external APIs, webhooks, payment sandboxes, and search integrations;
- caching behavior, PHP compatibility, and application logs;
- the final production domain and HTTPS plan.

Compare a small set of business-critical records between RunCloud and xCloud. A page loading successfully does not prove that the database, uploads, or background work migrated correctly.

**Expected result:** Site owners approve the demo copies, and every discrepancy has been resolved or documented.

## Step 11: Prepare the final synchronization and DNS cutover

Lower each production DNS record's TTL at least one existing-TTL interval before the cutover. Record the current DNS values and confirm that authoritative DNS now returns the lower TTL.

xCloud's public full-server guide does not document an incremental final-sync or merge procedure. If a site receives orders, registrations, comments, uploads, or other writes, arrange a supported recopy or final-sync plan with xCloud support before the maintenance window. Do not assume that starting another migration will merge changes safely.

Immediately before the final copy or approved cutover:
1. Put the source sites into maintenance or read-only mode.
2. Pause source cron jobs, queue workers, imports, webhooks, and other writers.
3. Keep the destination read-only and pause equivalent destination processing.
4. Complete the supported final copy or reconciliation.
5. Recheck critical record counts and recent data.

**Expected result:** No uncontrolled writes can create divergent source and destination data during cutover.

## Step 12: Switch DNS and verify HTTPS

Update the authoritative DNS records to the xCloud destination values. Wait for the authoritative response to show the new values, then verify the production domain over HTTPS.

Test the frontend, WordPress administrator, forms, uploads, redirects, email, scheduled work, and logs again through the production domain. Enable destination cron jobs and workers only after the destination is authoritative and the final data check passes.

**Expected result:** Production traffic reaches xCloud, the certificate is valid, and application data and background processing behave as expected.

## Step 13: Close the migration window safely

Keep the RunCloud server intact and read-only during the rollback window. Re-enable only the security and caching controls appropriate for the new xCloud environment. Remove the temporary xCloud migration key from the RunCloud root account, restore RunCloud's **Prevent root login** setting if it was previously enabled, and close any temporary firewall access.

Do not cancel the source server or delete its backups until the site owners accept the xCloud deployment and the rollback window expires.

**Expected result:** The xCloud sites are stable, temporary source access is revoked, and a usable rollback point remains.

## Verify the migration

The migration is complete when all of the following are true:
- Authoritative DNS resolves every production domain to the xCloud destination.
- HTTPS loads without certificate or mixed-content errors.
- Frontend pages, WordPress administration, forms, uploads, and redirects work.
- Recent business-critical records match the approved final source state.
- Destination cron jobs and workers run once, in the intended timezone and context.
- Application, PHP, and web-server logs show no unresolved migration errors.
- Site owners approve the production result.
- The source remains available and unchanged for the agreed rollback window.

## Troubleshooting

| Symptom | Likely cause | Fix |
|---|---|---|
| xCloud cannot connect to the source | TCP port 22 is blocked, the SSH port is different, root login is prevented, or the authentication method is wrong | Confirm the actual SSH port, open it in both firewalls, review RunCloud **SSH > Config**, and test the same root authentication method before retrying |
| The source connects but no sites appear | The workload is not WordPress, files or databases are not accessible to root, or the stack is unsupported | Confirm the workload and eligibility. Use site-level migration when full-server discovery is not supported |
| A RunCloud OpenLiteSpeed server is rejected | The source does not meet another prerequisite, despite OpenLiteSpeed support | Recheck Ubuntu version, x86-64 architecture, root access, security controls, and connectivity. Escalate with the recorded error if all published requirements match |
| The migration stops because of storage | The destination lacks space for site files, databases, and temporary copy data | Increase destination storage or reduce the selected migration set, then keep at least 1 GB free after the copy |
| The demo site loads but content is stale | New writes occurred on RunCloud after the copy | Keep both sides read-only and use the supported final-copy or reconciliation plan. Do not merge databases manually without an application-specific procedure |
| The production domain still reaches RunCloud | DNS has not been updated at the authoritative provider, or cached records have not expired | Verify the authoritative record and TTL, then wait for caches. Do not decommission RunCloud while traffic still reaches it |
| HTTPS fails after DNS cutover | DNS is not fully pointing to xCloud, or certificate issuance has not completed | Confirm authoritative DNS first, then complete the certificate workflow for the production domain and retest HTTPS |
| Scheduled work runs twice | Cron jobs or workers are active on both platforms | Pause both sides during final sync. After cutover, enable processing only on the authoritative xCloud destination |

## Common mistakes
- **Treating every RunCloud server as eligible.** RunCloud supports Ubuntu and architecture combinations that xCloud's current full-server guide does not list.
- **Confusing full-server migration with a server clone.** This workflow is for discovered WordPress sites, not every service or non-WordPress application on the VPS.
- **Leaving root login blocked.** xCloud's current full-server workflow requires root access even if RunCloud normally rejects root SSH sessions.
- **Skipping a verified backup.** A backup that has never completed or has no known restore path is not a rollback plan.
- **Going live before demo validation.** DNS cutover should follow application, data, upload, integration, and log checks.
- **Assuming the first copy includes later writes.** Stateful sites need a write freeze and a supported final synchronization or reconciliation plan.
- **Running workers on both platforms.** Duplicate cron jobs, emails, imports, and queue processing can corrupt state or repeat customer actions.
- **Deleting the source too early.** Keep RunCloud available until traffic has drained, validation passes, and the rollback window ends.

## Roll back to RunCloud

Rollback is a controlled cutover, not only a DNS change.
1. Put xCloud and RunCloud into maintenance or read-only mode.
2. Pause cron jobs, workers, imports, and webhooks on both platforms.
3. Identify any writes accepted by xCloud after cutover.
4. Choose the authoritative data store and reconcile the destination write delta back to RunCloud when a supported reverse-sync method exists. If none exists, document the data-loss risk before proceeding.
5. Restore the previous authoritative DNS values.
6. Wait until production traffic has drained from xCloud and reaches RunCloud again.
7. Verify HTTPS, recent data, forms, email, cron jobs, workers, and logs on RunCloud.
8. Resume writes and background processing on RunCloud only after verification.

Keep xCloud unchanged until the rollback result is accepted. This preserves evidence and a second recovery point.

## Frequently asked questions

### Does xCloud support full-server migration from RunCloud OpenLiteSpeed?

Yes. xCloud's current full-server migration guide explicitly states that RunCloud OpenLiteSpeed is supported. The server must still satisfy the published operating-system, architecture, root-access, security, and destination requirements.

### Can I use this guide for a RunCloud server on Ubuntu 22.04?

Not under the current published prerequisites. RunCloud supports Ubuntu 22.04, but xCloud's full-server guide lists Ubuntu 20.04 and Ubuntu 24.04 LTS x64. Use a site-level WordPress migration unless xCloud confirms a newer supported combination.

### Can I migrate without root SSH access?

Not with this full-server workflow. Use xCloud's site-level WordPress migration path when root access is unavailable or prohibited.

### Does full-server migration move non-WordPress applications?

This guide does not claim that it does. xCloud's published flow discovers and moves WordPress sites. Inventory and migrate non-WordPress services separately with a workflow supported for that application.

### Is the migration zero downtime?

No. Demo validation reduces risk, but stateful sites still need a short write freeze and a supported final-copy or reconciliation plan before DNS cutover.

## Related xCloud documentation
- [Full server migration to xCloud from any host](/docs/perform-a-full-server-migration-with-xcloud/) (the generic root-SSH flow this guide uses)
- [Migrate an existing WordPress website in xCloud](/docs/migrate-an-existing-wordpress-website-in-xcloud/) (site by site, no root needed)
- [Migrate from Cloudways to xCloud](/docs/migrate-from-cloudways-to-xcloud-full-server-migration/)
- [Site backups in xCloud](/docs/site-backups-in-xcloud/)
- [Enable HTTPS and configure SSL certificates](/docs/enable-https-in-xcloud-configure-ssl-certificates/)
- [xCloud vs RunCloud](/xcloud-vs-runcloud/) if you are still comparing the two

If you run into any issues migrating from RunCloud, feel free to reach out to our [support team](/docs/access-built-in-support-portal-in-xcloud/) for help.
