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

How to Set Up WordPress Staging on Hostperl VPS

By Raman Kumar

Share:

Updated on Aug 15, 2026

How to Set Up WordPress Staging on Hostperl VPS

WordPress staging on a VPS: the safe way to test changes

WordPress staging gives you a private copy of your live site so you can test plugin updates, theme edits, WooCommerce changes, and fixes before visitors see them. On a Hostperl VPS, that usually means one extra subdomain, one separate document root, and a database copied from production. If you already host on a Hostperl VPS, this setup keeps release work under control and makes rollback far easier.

This guide follows a fresh-server setup: you will SSH in, confirm the operating system, create a non-root admin, install the required packages, point a staging subdomain at the VPS, secure it with HTTPS, clone WordPress, and verify that the staging site works without touching live traffic.

For broader launch planning, Hostperl customers often pair staging with WordPress staging for safer launches in 2026 and technical SEO checks for AI Overviews before a redesign or content refresh.

Connect to the VPS and confirm the operating system

On your local computer, open your first SSH session to the server.

ssh root@203.0.113.10

Replace 203.0.113.10 with the real public IP assigned to your Hostperl server. If your provider gives you a non-root login first, use that same IP and the account name they issued.

On the VPS as root, detect the distribution before you install anything.

cat /etc/os-release

You should see either Ubuntu/Debian or AlmaLinux/Rocky Linux. The package and firewall commands below are separated so you do not mix them.

Create a non-root sudo user for staging work

Keep the root session open until the new login works. That way you do not lock yourself out halfway through setup.

Ubuntu and Debian

adduser deploy

This creates the deploy account. Set a strong password when prompted.

usermod -aG sudo deploy

This grants sudo access through the sudo group.

install -d -m 700 /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys

On the VPS as root, confirm the account is ready.

id deploy

Then open a second terminal on your local computer and test the new login.

ssh deploy@203.0.113.10

Once connected, verify sudo access.

sudo -v

You should be asked for the deploy password only if your key does not cover sudo. Keep the root session open until this succeeds.

AlmaLinux and Rocky Linux

useradd -m deploy
passwd deploy

This creates the account and sets its password.

usermod -aG wheel deploy

Rocky and AlmaLinux use the wheel group for sudo access.

install -d -m 700 /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys

Verify the account.

id deploy

Then test a second SSH login from your local computer.

ssh deploy@203.0.113.10
sudo -v

Update the server and install the web stack

WordPress staging only helps if the server underneath it is current. Start with package updates, then install the web server, PHP, database, and tools you need for cloning the live site.

Ubuntu and Debian

On the VPS as the non-root sudo user, update the system and install packages.

sudo apt update
sudo apt -y upgrade
sudo apt -y install nginx mariadb-server php-fpm php-mysql php-curl php-gd php-mbstring php-xml php-zip unzip rsync curl certbot python3-certbot-nginx

Check versions so you know what is running.

nginx -v
php -v
mysql --version

AlmaLinux and Rocky Linux

On the VPS as the non-root sudo user, update the system and install packages.

sudo dnf -y update
sudo dnf -y install nginx mariadb-server php-fpm php-mysqlnd php-curl php-gd php-mbstring php-xml php-zip unzip rsync curl certbot python3-certbot-nginx

Confirm the installed versions.

nginx -v
php -v
mysql --version

Prepare DNS and firewall rules for the staging subdomain

Use a dedicated hostname such as staging.example.com. Point its A record to the VPS public IP in your DNS panel. If you also manage nameservers and email authentication on the same domain, keep staging separate from mail records so testing does not affect delivery.

If you want a deeper planning checklist for launch work, Hostperl also covers panel migrations without downtime and panel selection for 2026, which helps agencies avoid awkward cutover windows.

Ubuntu and Debian with UFW

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status verbose

OpenSSH and HTTP/HTTPS should be allowed before you turn UFW on.

AlmaLinux and Rocky Linux with firewalld

sudo systemctl enable --now firewalld
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

On SELinux-enabled systems, keep the default policy in place and use the standard web root and ports described here.

Set up MariaDB and create the staging database

Use a separate database for staging. That keeps test imports away from the production site and gives you a clean reset point.

For database hardening and restore planning, see Hostperl’s PostgreSQL hardening guide and backup and restore runbooks. The same discipline applies to MySQL and MariaDB.

sudo systemctl enable --now mariadb
sudo mysql_secure_installation

Follow the prompts to set a root password, remove anonymous users, disable remote root login, and remove the test database.

sudo mysql

Then create the staging database and user.

CREATE DATABASE wordpress_staging CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpstaging'@'localhost' IDENTIFIED BY 'use-a-long-random-password';
GRANT ALL PRIVILEGES ON wordpress_staging.* TO 'wpstaging'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Replace the sample password with a real secret. You will store it in WordPress later, so keep it private.

Build the staging directory and download WordPress

Create a separate document root for staging. A clean layout makes it easy to tell production from testing.

sudo mkdir -p /var/www/staging.example.com/public
sudo chown -R deploy:deploy /var/www/staging.example.com

Now download WordPress into that directory.

cd /tmp
curl -LO https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
rsync -a wordpress/ /var/www/staging.example.com/public/

The files should now live under /var/www/staging.example.com/public.

Copy the production site and database into staging

Make a current backup first. If a restore fails, you want a fallback copy before you try again.

These steps are the part most customers care about before a launch. If your production site already has large media libraries, a staging clone prevents the “it worked on my laptop” problem and lets you verify plugin conflicts privately.

sudo mysqldump -u root -p live_wordpress > /tmp/live_wordpress.sql

Replace live_wordpress with your production database name. If your live site runs elsewhere, export it from that system using your normal backup method.

sudo mysql wordpress_staging < /tmp/live_wordpress.sql

Next, copy the production wp-content directory so themes, plugins, and uploads match live.

sudo rsync -a /var/www/example.com/public/wp-content/ /var/www/staging.example.com/public/wp-content/

Replace the source path with your real production document root.

Configure WordPress for the staging hostname

Create the WordPress configuration file from the sample and point it at the staging database.

cd /var/www/staging.example.com/public
cp wp-config-sample.php wp-config.php
nano wp-config.php

Paste the following database settings into the file, then save and exit with Ctrl+O, Enter, and Ctrl+X.

define( 'DB_NAME', 'wordpress_staging' );
define( 'DB_USER', 'wpstaging' );
define( 'DB_PASSWORD', 'use-a-long-random-password' );
define( 'DB_HOST', 'localhost' );

Set ownership so the web server can read the files but cannot casually rewrite everything.

sudo chown -R deploy:www-data /var/www/staging.example.com/public
sudo find /var/www/staging.example.com/public -type d -exec chmod 755 {} \;
sudo find /var/www/staging.example.com/public -type f -exec chmod 644 {} \;

Configure Nginx for staging and test syntax before reload

Use a dedicated Nginx server block. This keeps staging isolated from production and makes certificate issuance straightforward.

sudo nano /etc/nginx/sites-available/staging.example.com

Paste this full server block, replacing only the domain name if you use a different staging hostname.

server {
    listen 80;
    server_name staging.example.com;
    root /var/www/staging.example.com/public;
    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 ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 30d;
        access_log off;
    }
}

Enable the site and test Nginx syntax before reload.

Ubuntu and Debian

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

AlmaLinux and Rocky Linux

On RHEL-compatible systems, use /etc/nginx/conf.d/ instead of sites-available.

sudo tee /etc/nginx/conf.d/staging.example.com.conf >/dev/null <<'EOF'
server {
    listen 80;
    server_name staging.example.com;
    root /var/www/staging.example.com/public;
    index index.php index.html;

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

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
EOF
sudo nginx -t
sudo systemctl reload nginx

If syntax fails, the error message usually points to the file and line number. Fix that before you reload again.

Issue Let’s Encrypt for the staging domain

Once DNS points to the VPS and port 80 is open, request a certificate. That keeps browser warnings out of the way while you test.

sudo certbot --nginx -d staging.example.com

Enter the email address you want for renewal notices. Certbot should update the Nginx block and reload it automatically.

Check the renewal timer.

sudo systemctl status certbot.timer

Finish WordPress setup in the browser

Visit https://staging.example.com from your browser. If the DNS record is correct and the certificate is live, you should see the WordPress installer or your cloned site.

Log in to the staging dashboard, then change these values before you start testing:

  • Site title and timezone
  • Plugin update status
  • WooCommerce checkout settings if you run a store
  • Search engine visibility, which should stay disabled on staging

If you need to adjust URLs inside the cloned database, use the safer search-and-replace workflow described in WordPress Search and Replace on a Live Site in 2026. That matters when the production domain and staging subdomain both appear in content, widgets, or serialized data.

Verify the staging site from server and client

On the VPS as the non-root sudo user, confirm services are active and listening.

sudo systemctl status nginx mariadb php8.3-fpm

Adjust the PHP-FPM service name if your distribution ships a different version.

sudo ss -tulpn | grep -E ':80|:443|:3306'

You should see Nginx on 80 and 443, and MariaDB on 3306 only if it is listening locally.

On your local computer, run an HTTP check.

curl -I https://staging.example.com

Expect a 200, 301, or 302 response depending on your WordPress and redirect settings.

Do one functional smoke test next: log in, open a test post, upload a small image, and confirm the Media Library shows it. If this is WooCommerce, place a test order with a sandbox gateway and verify the order appears in the dashboard.

Common staging problems and how to fix them

  • DNS has not propagated: run dig +short staging.example.com from your local computer. If it does not return the VPS IP, update the A record and wait for propagation.
  • Nginx fails to reload: run sudo nginx -t on the VPS. The output shows the exact config line to correct.
  • PHP pages download instead of render: check the PHP-FPM socket path in the Nginx block with ls /run/php/ or ls /run/php-fpm/.
  • WordPress cannot connect to the database: confirm credentials in wp-config.php and test login with sudo mysql -u wpstaging -p wordpress_staging.
  • Certificate issuance fails: verify port 80 is open and the hostname resolves to the VPS before rerunning Certbot.

If you want staging that is ready for client sign-off, Hostperl VPS hosting gives you the control you need without oversizing on day one. For teams that run WordPress or WooCommerce migrations often, pairing a Hostperl VPS with a clear launch process reduces rollback risk and saves support time.

When the site is ready, move the production DNS record, keep the staging copy for regression testing, and verify the live cache after cutover.

FAQ

Should staging use the same domain as production?

No. Use a subdomain such as staging.example.com so cookies, cache, and search indexing stay separate.

Can I clone WooCommerce orders into staging?

You can copy the database, but do not process real payments there. Use sandbox payment settings and test accounts only.

How often should I refresh staging?

Refresh it before major plugin updates, theme changes, store launches, and content edits that affect templates or checkout flows.

Should staging be public?

Usually no. Add HTTP basic auth or IP restriction if the site contains client data or unpublished content.

What should I check before pushing staging live?

Test the homepage, critical forms, checkout, login, image uploads, mobile layout, and cache headers. Then confirm backups are current.