Blog

Why Dev, Staging and Prod? Because Production Isn't a Test Environment

· 5 min read
Three server modules connected by a glowing conveyor: an open workshop, a module scanning a package, and a sealed module marked with a shield

Here’s how a lot of WordPress sites get updated. Someone logs into the live site, clicks “Update all” on twelve plugins, and refreshes the home page to see if it’s still there. If it is, great. If it isn’t, the site is down, customers are looking at an error page, and the fix is happening live, under pressure, on the one copy of the site that matters.

That’s not a WordPress problem. It’s a process problem, and the fix is old and boring: three copies of the site, each with one job. Dev, staging and production.

Three environments, three jobs

  • Dev is where things get built and broken. It runs on your own machine or a private server. Nobody else sees it, so you can try anything: a new plugin, a theme change, a PHP upgrade. If it falls over, you shrug and try again.
  • Staging is a dress rehearsal. It’s a copy of production on the same kind of server, with the same PHP version, the same plugins and a recent copy of the real content. Changes go here before they go live, so you see exactly what production will do, without production paying for it.
  • Production is the real site. Nothing gets tried here. Changes arrive already tested, and the only surprise should be how uneventful the deploy was.

The point isn’t having three copies. The point is that every change has to pass through the other two before it reaches the one people use.

“But it’s just a WordPress site”

That’s exactly why it needs this. WordPress sites are built out of other people’s code. A typical site runs a theme from one company, plugins from a dozen more, and WordPress core on top, all updating on their own schedules. None of those developers tested their update against your exact combination. Staging is where you find out whether the combination still works.

Things staging catches that “update and pray” doesn’t:

  • A plugin update that conflicts with another plugin, or with your theme
  • A PHP version upgrade that breaks old code throwing new errors
  • A WordPress core release that changes behavior your site quietly depended on
  • A layout change that looks fine on your laptop and broken on a phone
  • A “small” CSS tweak that turns out to affect every page

Any one of these on production is downtime. On staging it’s a ticket.

The WordPress catch: code goes up, content comes down

Most web applications keep code and data cleanly apart. WordPress mixes them. Your theme and plugins are files, but the content, settings, menus and widget layouts live in the database, along with a lot of plugin configuration.

That gives you one rule that keeps the three environments sane:

Code moves up. Content moves down.

  • Code (the theme, plugins and configuration in files) is built in dev, tested on staging, then deployed to production.
  • Content is written on production, because that’s where your editors and your customers are. Staging gets refreshed with a copy of the production database whenever you need realistic data to test against.

What you don’t do is push a staging database over production. Every order, form entry, comment and post written on the live site since your last copy would be gone.

When you do copy the database down, WordPress stores full URLs in it, and some of them sit inside serialized PHP data. A plain text find-and-replace of the domain name breaks those serialized strings. Use a search-replace tool that understands serialization, so https://example.com becomes https://staging.example.com without corrupting anything.

Tell each copy what it is

Since version 5.5, WordPress has a built-in way to know which environment it’s running in. Set it in each copy’s wp-config.php:

define( 'WP_ENVIRONMENT_TYPE', 'staging' ); // local, development, staging or production

Your code can then ask with wp_get_environment_type() and behave differently. A staging site that sends real email is a classic accident. Imagine a thousand customers getting test order confirmations. A few lines stop that on every copy except production:

if ( 'production' !== wp_get_environment_type() ) {
	add_filter( 'pre_wp_mail', '__return_false' );
}

Staging housekeeping

A staging site is a full copy of your real site sitting on the internet. Treat it that way:

  • Put it behind a password. HTTP authentication on the whole staging domain keeps out search engines, scrapers and attackers in one step.
  • Keep it out of search. Turn on “Discourage search engines from indexing this site” in Settings → Reading as a second layer. A staging copy indexed by Google competes with your real site.
  • Switch off the outside world. Payment gateways in test mode, email blocked, newsletter and CRM integrations disconnected, scheduled jobs that talk to other services disabled.
  • Keep it current. A staging site running last year’s PHP version and a six-month-old database isn’t a rehearsal for anything. Match production’s server setup and refresh the data regularly.
  • Patch it too. An outdated staging copy with a known plugin vulnerability is a way into your real data.

What it costs

More than updating live, honestly. You need somewhere to run staging, a way to deploy code from one environment to the next, and the discipline to not “just quickly” fix something on production. Every change takes a little longer.

What you get back is that updates stop being events. Plugin updates, PHP upgrades and new features all become routine, because you already watched them work on staging. Production becomes the boring copy, and boring is exactly what you want from the site that pays the bills.

If your WordPress site matters to your business, the question isn’t whether you can afford a staging environment. It’s whether you can afford to keep testing on your customers.