Skip to main content
Blog|
How-to guides

How to create a WordPress staging site

|
Jun 1, 2026|15 min read
HOW-TO GUIDESHow to create a WordPressstaging siteHOSTNEYhostney.comApril 17, 2026

A staging site is a private copy of your live WordPress site that you use to test changes before visitors ever see them. Plugin updates, theme edits, core upgrades, a new checkout flow, a risky database migration – all of it happens on the copy first. If something breaks, it breaks somewhere nobody is looking, and your production site keeps serving traffic.

This guide covers what a staging site actually is, the three practical ways to set one up, how to push changes from staging to live without corrupting either, and how to keep the staging copy from showing up in Google.

What a staging site is (and what it is not)#

A staging site is a functional duplicate of your production site – same WordPress version, same plugins, same theme, same database content – running at a different URL that only you and your team can reach. It is not a backup (a backup sits in cold storage; a staging site is live and you interact with it), and it is not a local development environment (those run on your laptop and usually cannot reproduce server-level quirks like PHP version, MySQL settings, or the nginx config your host uses).

The three properties that define a real staging site:

  1. It runs the same code and the same data as production, or close enough that tests on staging predict behaviour on production.
  2. It is isolated. Changes on staging cannot corrupt the live database or overwrite live files.
  3. It is reachable by you but hidden from the public and from search engines.

If any of those three is missing, you have something else – a sandbox, a dev site, a copy on your laptop – and the conclusions you draw from testing on it may not hold once you deploy.

Why you actually need one#

The short version: every change to a WordPress site is a migration risk in miniature. A plugin update can deactivate a payment gateway. A theme switch can wipe the widget config. A PHP version bump can break a function that has not been touched in five years. A database change can leave orphaned rows that slow everything down.

Testing on production means your customers are the ones who find these problems. Testing on staging means you find them first.

Specific scenarios where staging pays for itself within one use:

  • Plugin updates. Especially WooCommerce, page builders, SEO plugins, caching plugins – anything that touches the database schema or the frontend rendering.
  • Theme changes. Switching themes rewrites widget areas, menu locations, and theme-specific options. Doing this on production leaves visitors staring at a half-configured site while you re-place every widget.
  • PHP version upgrades. Old plugins call old functions. A staging site running the target PHP version surfaces fatal errors before they hit production. See end-of-life PHP and the risks of running an unsupported version for why this matters beyond just staging.
  • Database-heavy changes. Bulk post edits, custom field migrations, user role restructures – all safer on a copy you can throw away when you are done.
  • Pre-migration dry runs. Before migrating WordPress to another hosting provider, clone to staging on the new host first, confirm everything works, then cut over DNS.

The three ways to set up staging#

There are three realistic approaches, in order of how much control they give you and how much manual work is involved.

1. Subdomain approach (manual clone)#

You create a subdomain like staging.yourdomain.com , copy the WordPress files there, clone the database, update wp-config.php and a handful of database options, and you are done. This is the most flexible approach and the one that works on any host, including hosts that do not have a staging feature.

Step-by-step:

  1. Create the subdomain. In your hosting panel, add staging.yourdomain.com and point it at a new directory (for example /staging/ ). On most managed hosts this provisions the directory, an SSL certificate, and an nginx or Apache config for you.
  2. Copy the files. SSH or SFTP into the server and copy the entire WordPress root from your live site into the staging directory. rsync -a /path/to/live/ /path/to/staging/ is the cleanest way if you have shell access. If not, a plugin like All-in-One WP Migration or UpdraftPlus can export and re-import, but rsync is faster and preserves file permissions.
  3. Clone the database. Create a new empty database for staging (for example yoursite_staging ). Export the live database with mysqldump , then import it into the staging database. mysqldump -u user -p live_db > dump.sql && mysql -u user -p staging_db < dump.sql . If you do not have SSH, phpMyAdmin can do the same thing through a browser.
  4. Update wp-config.php in the staging directory. Change DB_NAME to your staging database. Update DB_USER and DB_PASSWORD if you created separate credentials. Change the authentication keys and salts to new values (generate them at https://api.wordpress.org/secret-key/1.1/salt/ ) so sessions do not bleed between live and staging. For more on what each of these settings does, see wp-config.php explained: what every setting does.
  5. Rewrite the site URL in the database. WordPress stores siteurl and home in the wp_options table. It also stores the domain in serialised option values, post content, and meta fields. Do not run a blind UPDATE wp_options SET option_value = REPLACE(...) – that corrupts serialised data. Use WP-CLI from the staging directory: wp search-replace 'https://yourdomain.com' 'https://staging.yourdomain.com' --all-tables --precise . The --precise flag handles serialised data correctly. This is the same technique used when changing a WordPress domain name – a staging clone is effectively a domain change against a copy of the database.
  6. Block indexing. In the staging WordPress admin, go to Settings > Reading and tick “Discourage search engines from indexing this site.” Also add HTTP basic auth in front of the whole subdomain (covered below). If you are trying to keep a site non-public for a different reason – not a duplicate of live, but a site that has not launched yet or needs temporary maintenance coverage – see how to hide pages, make your site private, or put it under construction for the right mechanism in each case.
  7. Test. Load https://staging.yourdomain.com in a browser. Log in. Walk the site. If pages render but images are missing, the URL replacement missed a table – rerun wp search-replace against the specific table.

The subdomain approach gives you full control. It is also the one that teaches you the most about how WordPress stores its URLs, which pays off later when you have to debug a broken migration.

2. Plugin approach#

Plugins like WP Staging, WP STAGING Pro, BlogVault, and Duplicator automate most of the above. You click a button, the plugin clones files and database into a subdirectory (typically yoursite.com/staging/ instead of a real subdomain), rewrites the URLs, and gives you a separate login.

What the plugin approach does well:

  • No SSH needed.
  • URL rewriting is handled correctly (these tools know about serialised data).
  • Push-to-live features in paid versions can sync specific tables or files back to production.

What to watch for:

  • Staging in a subdirectory ( yoursite.com/staging/ ) shares nginx config, PHP-FPM pool, and sometimes cache headers with your live site. A misconfigured staging can cause odd caching issues on the live domain.
  • Free versions usually clone files and database but leave out the “push to live” feature. You can test, but you cannot easily deploy changes back.
  • The plugin has to stay installed on both sides. If you deactivate it, you lose the connection between staging and live.

Plugins are the right call when you do not have shell access or when you want a one-click workflow. They are the wrong call when you care about isolation – a subdirectory staging is not as separated from production as a real subdomain or a separate hosting account.

3. Hosting panel approach#

Some hosts provide a one-click staging feature in their control panel. You pick your site, click “create staging,” and the platform clones files and database into an isolated environment, usually at a random subdomain like staging-123.hostname.com . You get a separate login, the subdomain is automatically noindexed, and a “push to live” button handles the reverse sync.

This is the fastest approach when your host offers it. The quality varies a lot between providers – some clone properly and isolate cleanly, others just copy files into a subdirectory and call it staging. Ask specifically:

  • Does staging run in an isolated environment (separate database, separate PHP process) or share with production?
  • How does push-to-live handle the database – full overwrite, table selection, or differential merge?
  • Is staging accessible only to logged-in panel users, or is it a public URL?
  • Does the staging site consume your hosting plan’s disk and CPU quota, or is it separate?

If your host does not yet offer staging, fall back to the subdomain approach. It takes an hour the first time and fifteen minutes every time after.

Push-to-live: what to sync and what to leave alone#

The hardest part of staging is not creating it. It is deciding what to sync back to production when your testing is done.

A WordPress site has two kinds of state: code (themes, plugins, custom files in wp-content ) and data (everything in the database). These change at different rates, and they have different owners.

  • Code changes come from developers. On staging, you update a plugin, edit a theme file, add a custom post type in code. These changes should go to production.
  • Data changes come from editors and visitors. On production, an editor publishes three new blog posts, a customer places four orders, a comment is posted. These changes are happening while you test on staging. If you push staging’s database back to live, you overwrite those changes.

The safe sync workflow:

  1. On staging, only change code and configuration. Avoid creating test posts that you then want to keep, and avoid editing settings that also got changed on production in the meantime.
  2. When testing is done, push files only: sync wp-content/themes/ and wp-content/plugins/ from staging to production. Leave wp-content/uploads/ alone – uploads are owned by production. rsync -a --exclude=uploads /staging/wp-content/ /live/wp-content/ works.
  3. For database changes that must reach production (custom field schema changes, new settings), apply them manually on production after the file sync, not by overwriting the database.
  4. Run wp cache flush on production afterwards. If you use a page cache like Hostney Cache, purge it too. Plugin and theme changes invalidate rendered HTML.

The reverse – pulling production down to refresh staging – is easier: you can overwrite staging’s database and files from a fresh production backup any time you want, because staging has no data you care about keeping. Make this your routine. Refresh staging from production before every round of testing so you are not testing against stale data.

Keeping staging private#

A staging site that Google can crawl is worse than useless. Duplicate content, leaked pre-release features, broken test pages in search results. Belt-and-braces is the right posture here – apply all three of these, not just one.

1. robots.txt and noindex. In the staging WordPress admin, Settings > Reading > Discourage search engines. This adds a meta noindex tag to the pages and generates a robots.txt that asks crawlers to skip the site. Well-behaved crawlers obey it. Ill-behaved ones do not.

2. HTTP basic auth. Add a username and password requirement in front of the entire subdomain. In nginx:

location / {
    auth_basic "Staging";
    auth_basic_user_file /etc/nginx/staging.htpasswd;
    # ... rest of the location block
}

Create the htpasswd file with htpasswd -c /etc/nginx/staging.htpasswd yourname . Now nothing – browsers, crawlers, curious visitors – reaches the site without a password. This is the strongest layer. The full walkthrough of basic auth on WordPress, including the WP-Cron and REST API exceptions needed so the site still functions while protected, is in how to password protect a WordPress site, page, or directory.

3. IP allowlist. If you and your team always work from a static IP or a VPN, restrict the subdomain to those IPs at the firewall or server level. Everything else gets a 403.

Do not rely on “security through obscurity” – just picking a random subdomain like stg-7x2.yourdomain.com and hoping nobody finds it. Subdomains leak through certificate transparency logs, and anyone searching CT logs sees them within minutes of the SSL certificate being issued.

The blank-page trap: security plugins and absolute paths#

The single most common reason a freshly cloned staging site shows a blank page or a 500 error has nothing to do with the clone itself. It is security and performance plugins writing absolute filesystem paths into .htaccess and .user.ini .

Wordfence, iThemes Security (now Solid Security), All In One WP Security, and several caching plugins bootstrap themselves before WordPress loads by prepending a file. Wordfence, for example, writes a line like auto_prepend_file = "/home/your-user/public_html/wordfence-waf.php" into .user.ini . iThemes injects path constants and rewrite rules into .htaccess . Those paths point at your production home directory.

When you clone to staging, the files come across verbatim, absolute paths and all. The staging copy lives in a different directory, so the prepended file path now points somewhere that does not exist on the staging install. PHP tries to load it, fails before WordPress even starts, and you get a white screen or a 500.

The fix:

  1. Open the staging copy’s .htaccess and .user.ini in the document root over SSH, SFTP, or a file manager.
  2. Find the plugin-managed block. It is usually wrapped in markers like # BEGIN Wordfence / # END Wordfence or ; Wordfence WAF , and the absolute /home/... path inside is the giveaway.
  3. Delete the block, or rewrite the path to point at the staging home directory.
  4. Reload staging. Once WordPress runs, deactivate or reconfigure the plugin from wp-admin so it stops pinning the old path.

This is not specific to any host – it is how auto_prepend_file -style hardening works everywhere. Re-cloning will not help because the same files come back over. Either edit the paths out on the staging copy, or temporarily disable the plugin on production before you clone. The same trap bites in reverse: if you ever push staging’s .htaccess or .user.ini back to production, you can pin production to a path that no longer exists and take the live site down. Leave those two files out of any push unless you specifically tested changes to them.

Common mistakes that make staging useless#

  • Testing with stale data. Staging was cloned three months ago and does not have the 200 products the merchandising team added since. A plugin update works on staging and breaks on production because the data shape is different. Refresh staging from production before testing.
  • Different PHP version on staging. A plugin update passes on staging running PHP 8.1 and fatals on production running PHP 7.4. Match the PHP version.
  • Different plugin set on staging. Someone deactivated a plugin on staging six weeks ago to test something. That plugin is what conflicts with the update on production. Keep the active plugin list identical.
  • Not testing the admin. The frontend loads on staging, so you call it good. But the admin edit screen for WooCommerce products throws a JavaScript error. Walk the admin too, especially the screens for any plugin you updated.
  • Forgetting to disable emails. Staging inherits the email settings from production. Now it fires order confirmation emails to real customers when you test a checkout. Set WP_ENVIRONMENT_TYPE to staging in wp-config.php and install a plugin like WP Mail Log or use a catch-all mail plugin to intercept outbound mail. Or just change the SMTP credentials on staging to a test mailbox.

How Hostney handles staging#

Hostney’s WordPress manager has a dedicated Staging tab on every WordPress install. Click Create staging, choose whether to clone the uploads folder, and the platform clones the live site to an unguessable .staging.hostney.app URL with its own separate database. The clone happens in the background and the tab flips to “Active” when the worker finishes. Staging is hidden from search engines automatically (server-level X-Robots-Tag: noindex plus a footer banner so any human visitor knows they are not on the real site).

Once staging is up, you get one-click admin login – Hostney generates a single-use token, opens the staging wp-admin in a new tab, and signs you in as your existing admin user, so there is no separate staging password to remember. From there you can change the PHP version, the frontend (Nginx or Apache), and every php.ini directive on the staging copy independently of production – so a PHP-version dry run or an Nginx-to-Apache test is one click, not a separate hosting setup. You can also reach the staging copy’s files over SSH/SFTP, FTPS, and the file manager, and its database lives next to your production database in MySQL manager. Same tooling, different scope.

The centerpiece is Push to production: pick exactly what to promote – files, specific database tables, or both – with smart defaults that pre-exclude tables that typically accumulated real data while you were working on staging (comments, WooCommerce orders, form entries, Action Scheduler queues). Every URL inside the pushed tables is rewritten automatically from the staging URL to the production URL, including PHP-serialized values inside wp_options and wp_postmeta . The push has guardrails built in for exactly the traps described above: wp-config.php is always excluded so production keeps its own database credentials, uploads/ and .htaccess are left alone unless you opt in, and the staging marker plugin that injects the noindex header can never be pushed. A production snapshot is taken automatically before each push (default-on), so the Snapshots tab is your one-click rollback path if anything in the push goes wrong. The push is also non-destructive on the staging side, so the copy stays exactly as it was and you can keep iterating for the next round.

Stagings that sit idle auto-prune after a plan-defined window to keep your disk usage in check, with an email warning before deletion – so you are not paying for forgotten clones, but a long migration project survives as long as you interact with it. If you would rather not use the built-in staging tab – some teams prefer a fully manual subdomain workflow – the subdomain approach described earlier still works on Hostney. Container isolation per account means a separate subdomain runs in the same isolated environment as your live site (same PHP version, same nginx config, same MySQL instance), which is exactly what you want for staging. Tests on either kind of staging copy predict production behaviour closely because the underlying stack is identical.

If you are evaluating hosting partly because you want a real staging workflow, the question to ask any provider is not “do you offer staging” but “how does your staging work” – the three-property checklist at the top of this article (same stack, isolated, private) is the filter that separates real staging from a directory copy sitting next to your live site.

Summary#

Set up staging before you need it, not after. The first time you use it to catch a plugin update that would have taken your site down on a Friday afternoon, the fifteen minutes of setup pays itself back many times over. Use a real subdomain when you can, a plugin when you cannot, and a hosting panel feature when your host offers one that meets the isolation and privacy requirements. Keep staging refreshed from production, keep production updates flowing from staging as code only, and keep Google’s crawlers out with both robots rules and a password.