Duplicating a WordPress site to staging
Testing an update or a development on a faithful copy of the site, before touching production, almost always means changing the URL (site.fr to preprod.site.fr or a subfolder). That URL change is the most commonly mishandled technical point of this kind of copy.
Why changing the URL breaks settings if done wrong
WordPress stores some of its data (theme settings, widget configuration, certain metadata, plugin options) as serialised PHP data in the MySQL database’s text columns. A serialised string encodes the exact length of each substring it contains, for example s:19:"https://old-site.fr". If the URL is replaced with a plain SQL search-and-replace, using a query like UPDATE wp_options SET option_value = REPLACE(...), the declared number before the quotes no longer matches the new string length, and WordPress fails to unserialise the data.
A staging copy multiplies the chances of falling into this trap, because the URL often changes a second time afterwards: a temporary test address at copy time, then a permanent staging address once the environment settles. Every change has to go through the same tool, not just the first one.
The result isn’t always visible straight away: reset theme settings, disappearing widgets, emptied plugin options, sometimes without a clear error message. The correct method uses a tool that recalculates these lengths on every replacement, typically WP-CLI’s wp search-replace old-url new-url --all-tables command, or a migration plugin that does this work internally, such as All-in-One WP Migration or WP Migrate DB.
What to plan for beyond a standard copy
- Blocking search engine indexing: indexed duplicate content harms the main site’s rankings
- Cutting real email sending (order confirmations, notifications) so no real customer is alerted during testing
- Neutralising payment gateways by keeping them strictly in test mode, so a real payment is never triggered
- A growing gap between staging and production over time if no regular resync is planned
How I run a staging duplication
-
Full copy of files and database
I duplicate all site files and export the database to the staging environment.
-
URL replacement with wp search-replace
The production URL is replaced with the staging one using WP-CLI, which correctly recalculates serialised data lengths.
-
Blocking indexing
I add a noindex tag or a dedicated robots.txt for staging, so no search engine indexes the duplicate.
-
Neutralising outgoing emails
I use an email capture service or disable the sending plugin, so no notification reaches a real customer from staging.
-
Switching payment gateways to test mode
Real payment credentials are swapped for their test equivalents, so no real money movement is ever triggered.
-
Resyncing when needed
If the gap between staging and production grows too large over time, I run a full copy from production again rather than patching staging case by case.
Related reading
-
Zero-downtime host migration
The same serialisation mechanism applied to a real host switch.
-
Understanding PHP serialisation
The full definition of the mechanism and its pitfalls.
-
Backing up your shop before any work
What to back up before any site copy.
-
Enabling WordPress debug mode
Useful for spotting a silent error on the staging environment.
Describe your need in one minute
A few targeted questions so I can reply with an estimate rather than another questionnaire.