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

How to Clone a WordPress Site with Staging in 2026

By Raman Kumar

Share:

Updated on Aug 2, 2026

How to Clone a WordPress Site with Staging in 2026

Why staging matters before you change a live WordPress site

If you need to clone a WordPress site with staging, the goal is straightforward: test updates, design changes, plugin swaps, and content edits without putting the live site at risk. In 2026, that matters even more. Customers do not wait around for broken checkouts or a plugin conflict that only appears during business hours.

This guide walks through a practical staging workflow on a fresh Hostperl VPS: create the site copy, secure it, point a test domain or subdomain at it, verify everything, and then decide how to publish changes back to production. If you are still choosing infrastructure, a Hostperl VPS gives you the control you need for safe staging, while keeping hosting costs predictable for agencies and store owners.

If your move includes a panel migration or a provider switch, this approach also fits Hostperl’s migration guidance, including Migrating to DirectAdmin in 2026 and Set Up a New Hosting Site in cPanel or Plesk when the live site sits behind a control panel.

What you need before you clone the site

  • Root or sudo access on the VPS.
  • A working WordPress site with database credentials.
  • A staging domain or subdomain, such as staging.example.com.
  • A fresh backup of files and database.
  • Enough disk space for a second copy of the site.

Use these placeholders throughout the tutorial: SERVER_IP is your VPS IP, DOMAIN_NAME is your live domain, STAGING_DOMAIN is the clone hostname, APP_USER is the non-root admin account, and WP_DIR is the WordPress document root. Example values: 203.0.113.10, example.com, staging.example.com, hostperladmin, and /var/www/example.com.

Connect to the VPS and confirm the operating system

On your local computer, open SSH to the server. If your provider uses a default non-root account, replace root with that username.

ssh root@SERVER_IP

You should land on the server shell. If you use keys, SSH should not ask for a password.

On the VPS as root, detect the OS before installing anything else.

cat /etc/os-release

Look for ID=ubuntu, ID=debian, ID=almalinux, or ID=rocky. The next commands are separated for Debian-based and RHEL-compatible systems.

Create a non-root admin account first

Keep your original root SSH session open until the new login works. That avoids lockouts while you adjust permissions.

Ubuntu and Debian

On the VPS as root, create the account, add sudo access, and prepare SSH keys.

adduser APP_USER
usermod -aG sudo APP_USER
install -d -m 700 -o APP_USER -g APP_USER /home/APP_USER/.ssh

Replace APP_USER with your admin username. The account should now exist, belong to the sudo group, and have a locked-down SSH directory.

Now copy your public key into place.

cat > /home/APP_USER/.ssh/authorized_keys <<'EOF'
PASTE_YOUR_PUBLIC_KEY_HERE
EOF
chown APP_USER:APP_USER /home/APP_USER/.ssh/authorized_keys
chmod 600 /home/APP_USER/.ssh/authorized_keys

Open a second terminal and test the new login.

ssh APP_USER@SERVER_IP
sudo -v
whoami

You want whoami to return your non-root username and sudo -v to accept your password or key-based elevation.

AlmaLinux and Rocky Linux

On the VPS as root, create the account and add wheel access.

useradd -m APP_USER
passwd APP_USER
usermod -aG wheel APP_USER
install -d -m 700 -o APP_USER -g APP_USER /home/APP_USER/.ssh

Then install the public key and secure the file.

cat > /home/APP_USER/.ssh/authorized_keys <<'EOF'
PASTE_YOUR_PUBLIC_KEY_HERE
EOF
chown APP_USER:APP_USER /home/APP_USER/.ssh/authorized_keys
chmod 600 /home/APP_USER/.ssh/authorized_keys

Test the new session in another terminal before changing any root-login settings.

ssh APP_USER@SERVER_IP
sudo -v
id

If id shows wheel, the privilege path is ready.

Update packages and install the tools you need

Staging works best on a clean, patched host. Update the system first, then install the database and web tools you will use to copy the site.

Ubuntu and Debian

On the VPS as the non-root sudo user, refresh packages and install utilities.

sudo apt update
sudo apt -y upgrade
sudo apt -y install rsync mariadb-client unzip curl

Expect the upgrade to finish without errors. rsync will copy files, mariadb-client will dump or restore the database, and curl helps with smoke tests.

AlmaLinux and Rocky Linux

On the VPS as the non-root sudo user, use dnf instead.

sudo dnf -y update
sudo dnf -y install rsync mariadb curl unzip

After the update, check that the kernel and core packages are current enough for your WordPress stack.

Back up production before you clone anything

Clone first, but never skip a backup. If staging overwrites a file or a URL replacement goes wrong, you need a clean rollback point.

On the VPS as the non-root sudo user, create a backup directory and capture files plus database.

mkdir -p ~/wp-backups/$(date +%F)
rsync -aH --delete /var/www/DOMAIN_NAME/ ~/wp-backups/$(date +%F)/files/

If you prefer a database dump, export it now. Replace DB_NAME and DB_USER with your real values from wp-config.php.

mysqldump -u DB_USER -p DB_NAME > ~/wp-backups/$(date +%F)/DB_NAME.sql

You should end with a dated folder containing site files and a SQL dump. Store that backup off-server as well if this site matters to revenue.

For a broader recovery plan, Hostperl’s Shared Hosting to VPS: What Changes in 2026 explains why independent backups become more important once you leave a shared environment.

Copy the live site into a staging directory

Now create the staging document root and copy the production files into it. This keeps the live site untouched.

On the VPS as the non-root sudo user, create the new directory and sync files.

sudo mkdir -p /var/www/STAGING_DOMAIN
sudo rsync -aH --delete /var/www/DOMAIN_NAME/ /var/www/STAGING_DOMAIN/

Replace the source path with your current WordPress root. If your live site lives in /var/www/html, use that instead. The clone should now contain wp-admin, wp-content, wp-includes, and wp-config.php.

Adjust ownership so your web server can read the files.

sudo chown -R www-data:www-data /var/www/STAGING_DOMAIN

On AlmaLinux and Rocky Linux, the user is often apache or the PHP-FPM pool account, so confirm your web server ownership before changing it broadly.

Clone the database and point WordPress at staging

The file copy is only half the job. Staging needs its own database or at least its own database prefix to prevent accidental writes to production.

On the VPS as the non-root sudo user, create a staging database and user. Use your preferred root database account.

mysql -u root -p

Inside the MySQL or MariaDB prompt, run this example. Replace passwords before you paste it into a terminal history if you prefer to keep them private.

CREATE DATABASE wp_staging DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_staging_user'@'localhost' IDENTIFIED BY 'REPLACE_WITH_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON wp_staging.* TO 'wp_staging_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Import the production database into the clone.

mysqldump -u DB_USER -p DB_NAME | mysql -u wp_staging_user -p wp_staging

Next, edit the staging wp-config.php. Use your editor of choice.

sudo nano /var/www/STAGING_DOMAIN/wp-config.php

Replace the database values so the clone uses the staging database. Save and exit after updating these lines:

define('DB_NAME', 'wp_staging');
define('DB_USER', 'wp_staging_user');
define('DB_PASSWORD', 'REPLACE_WITH_STRONG_PASSWORD');
define('DB_HOST', 'localhost');

If the live site uses a custom table prefix, keep it consistent in staging unless you are intentionally separating it.

Replace live URLs with the staging domain

WordPress stores absolute URLs in the database. If you skip this step, the clone may keep redirecting to the production site.

On the VPS as the non-root sudo user, use WP-CLI if it is installed. If you do not have it, use a search-and-replace tool that understands serialized data.

cd /var/www/STAGING_DOMAIN
wp search-replace 'https://DOMAIN_NAME' 'https://STAGING_DOMAIN' --skip-columns=guid --all-tables

If wp is not installed, check the URLs with a quick SQL query after replacing the old and new domains.

mysql -u wp_staging_user -p wp_staging -e "SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl','home');"

You want both values to show https://STAGING_DOMAIN. That confirms the clone points away from production.

Set up the staging virtual host

Choose the web server already running on the VPS. The config below assumes Nginx, which is the most common setup for WordPress staging on a VPS.

Ubuntu and Debian with Nginx

On the VPS as the non-root sudo user, create a server block for the clone.

sudo nano /etc/nginx/sites-available/staging.conf

Paste this configuration, then save and exit.

server {
    listen 80;
    server_name STAGING_DOMAIN;
    root /var/www/STAGING_DOMAIN;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Enable the site and test the syntax before reloading Nginx.

sudo ln -s /etc/nginx/sites-available/staging.conf /etc/nginx/sites-enabled/staging.conf
sudo nginx -t
sudo systemctl reload nginx

A successful nginx -t ends with syntax is ok and test is successful.

AlmaLinux and Rocky Linux with Nginx

On the VPS as the non-root sudo user, create a server block under /etc/nginx/conf.d/.

sudo nano /etc/nginx/conf.d/staging.conf

Use the same server block, but keep the file in the RHEL-compatible location.

server {
    listen 80;
    server_name STAGING_DOMAIN;
    root /var/www/STAGING_DOMAIN;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi.conf;
        fastcgi_pass unix:/run/php-fpm/www.sock;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Test and reload.

sudo nginx -t
sudo systemctl reload nginx

Open the firewall and add HTTPS when the clone is ready

Keep staging private until the site works. Then open the web ports and add TLS so logins and preview traffic are encrypted.

Ubuntu and Debian with UFW

On the VPS as the non-root sudo user, allow SSH, HTTP, and HTTPS.

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status verbose

Expect UFW to show the new rules as allowed. If UFW was inactive, enable it only after SSH is already permitted.

AlmaLinux and Rocky Linux with firewalld

On the VPS as the non-root sudo user, add the web services.

sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Use Let’s Encrypt once DNS for STAGING_DOMAIN points at the VPS. If you are still testing, you can skip TLS until the clone is stable, then issue the certificate later.

For teams planning long-term maintenance, Hostperl’s Technical SEO Audit for 2026 pairs well with staging because you can test canonicals, redirects, and schema before pushing changes live.

Lock staging down with basic access controls

WordPress staging should not be indexed or browsed freely. Add one of these protections before you share the URL internally.

  • HTTP basic auth at the web server.
  • IP allowlisting for office or VPN addresses.
  • Search engine discouragement in robots.txt.
  • A sitewide “noindex” header for the staging host.

A simple robots.txt is not enough by itself, but it helps prevent accidental indexing.

cat > /var/www/STAGING_DOMAIN/robots.txt <<'EOF'
User-agent: *
Disallow: /
EOF

Then check the file is reachable at https://STAGING_DOMAIN/robots.txt.

Run a full verification from server and browser

Before you hand the clone to a client, confirm the services are healthy and the site loads from the staging hostname.

On the VPS as the non-root sudo user, check service status and listening ports.

sudo systemctl status nginx php8.3-fpm --no-pager
sudo ss -ltnp | grep -E ':80|:443|:9000'

On AlmaLinux and Rocky Linux, the PHP service may be named php-fpm. Adjust the service name to match your installed version.

On your local computer, test the site with curl.

curl -I https://STAGING_DOMAIN
curl -s https://STAGING_DOMAIN | head

You want a 200 or a clean redirect to HTTPS, not a redirect loop or a production hostname in the response body.

Log into WordPress in a browser and make a harmless change, such as editing a draft post title or updating a widget. That confirms the database connection, file permissions, and PHP runtime are all working together.

Push staging changes back to production safely

Once the clone is approved, publish only the changes you need. Do not overwrite the whole site unless you really intend to replace production.

The safest path is usually one of these: database export/import for content changes, selective theme or plugin sync for design changes, or a deployment tool that copies only the files you edited. If you are migrating panels at the same time, review cPanel vs Plesk for Hosting Migrations in 2026 before you decide where the live site should sit.

For many small businesses, a shared hosting plan is enough for a brochure site, but a staging workflow becomes much easier on a VPS once you manage a store, a membership site, or multiple client sites.

Hostperl can help you keep staging and production separated without turning routine updates into risky release nights. If you want room for WordPress, WooCommerce, and test environments, start with a Hostperl VPS and scale as the site grows.

For agencies, that setup is easier to manage when you also plan your hosting panel and migration path early.

Troubleshooting the most common staging problems

Staging redirects to the live domain

Check:

mysql -u wp_staging_user -p wp_staging -e "SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl','home');"

If the values still show the live domain, run the search-and-replace again or update the rows directly. Clear any cache plugin and browser cache afterward.

White screen or PHP errors

Check the logs:

sudo tail -n 50 /var/log/nginx/error.log
sudo journalctl -u php8.3-fpm -n 50 --no-pager

If the logs mention permission errors, fix file ownership. If they mention a missing extension, install the package your plugin needs and restart PHP-FPM.

403 Forbidden on staging

Check permissions:

namei -l /var/www/STAGING_DOMAIN
ls -ld /var/www/STAGING_DOMAIN

Directories should usually be 755, and WordPress files should be readable by the web server user. Wrong execute bits on a parent directory often cause the 403.

Changes do not appear after you save them

Check caching:

curl -I https://STAGING_DOMAIN | grep -i cache
wp cache flush

If you use a CDN or object cache, clear that layer too. Many staging issues are cache problems, not WordPress problems.

Final checks before you call the clone ready

  • The staging URL opens over HTTPS.
  • WordPress login works on the clone only.
  • Database writes stay inside the staging database.
  • Plugins and themes load without PHP errors.
  • The live site remains unchanged during testing.

That is the point of a proper clone: you get a safe place to test updates, and your customers never see the unfinished work. If you want help choosing the right hosting setup for a WordPress build that needs staging from day one, Hostperl’s panel comparison guide and VPS hosting options are good starting points.

FAQ

Should staging use a separate database?

Yes. A separate database prevents test edits from overwriting production content, order data, or plugin settings.

Can I clone WordPress on shared hosting?

You can, but file permissions, cron control, and database isolation are usually easier on a VPS or a panel plan that supports subdomains cleanly.

Do I need a separate domain for staging?

A subdomain is usually enough. Use a separate domain only if your workflow needs stronger separation for client reviews or testing.

How do I stop search engines from indexing staging?

Use robots blocking, noindex headers, and access control. Do not rely on robots.txt alone.

What is the safest way to publish staging changes?

Push only the changed files or database tables. Avoid full overwrites unless you have a verified backup and a planned maintenance window.