"It worked on stage" is only reassuring if stage is a faithful rehearsal of production. On many Drupal platforms it is not: a different PHP version, no CDN, a database last refreshed a year ago, a module enabled on stage that production never had. Each difference is a place where a release can pass testing and still fail. This article covers how to structure environments so that stage predicts production, while keeping the differences that genuinely need to exist.
The environments and their jobs
| Environment | Job | Data |
|---|---|---|
| Local | Day-to-day development on each developer's machine | Sanitized copy, refreshed as needed |
| Dev | Integrating everyone's work; first place code runs on real infrastructure | Sanitized copy |
| Stage | Final verification and sign-off, as close to production as possible | Recent sanitized copy of production |
| Production | Serving visitors and editors | The real thing |
Some teams add short-lived feature environments for reviewing a single change. They are valuable when several streams of work run at once, as long as they are built the same way as the others.
What must match production
- PHP version and extensions, database engine and version, web server configuration
- The caching layers: CDN or reverse proxy, page caches, Redis or Memcached
- The search service and its configuration
- File storage approach (shared storage, object storage)
- The deployment process itself: the same pipeline and the same
drush deploysteps
Building every environment from the same infrastructure as code is the most reliable way to guarantee this. Hand-built environments drift.
What should differ, and how
Some differences are necessary: stage must not send email to real people, development needs debugging tools, production should not show errors on screen. Drupal handles these cleanly:
- Config Split. The Config Split module lets you keep environment-specific configuration, such as enabling Devel on dev only or pointing integrations at sandboxes, in separate sets that are activated per environment. The main configuration stays identical everywhere.
- Settings per environment. Database credentials, API keys, and environment flags come from environment variables or a secrets store, read by
settings.php. Nothing secret is committed to the repository. - Configuration overrides in
settings.phpfor single values, such as turning off error display on production.
Handling data between environments
- Refresh stage regularly from production, so testing reflects real content volume and edge cases.
- Sanitize every copy.
drush sql:sanitizereplaces user emails and passwords; add steps for any other personal data your site collects, such as webform submissions. - Stop outgoing mail on non-production, or route it to a catch-all mailbox.
- Skip bulk file copies. The Stage File Proxy module fetches missing public files from production on demand, so lower environments do not need a full copy of every upload.
Promotion rules
- Code and configuration move up only through version control and the pipeline.
- One build artifact is promoted through each environment, rather than rebuilt for each.
- Configuration is exported from dev, reviewed like code, and imported on deploy. Nobody changes configuration directly on production.
- Content moves down only, and only sanitized.
- Stage sign-off happens on stage, not on dev.
Common drift to look for
drush config:statuson production shows differences, meaning someone changed configuration directly.- A module enabled on stage but not in the exported configuration.
- Stage running without the CDN or cache backend, hiding caching bugs.
- A stage database many months old.
Secrets and credentials
Each environment should have its own database password, API keys, and integration credentials, stored in a secrets manager rather than in files. That way a leaked development credential cannot touch production, and rotating a key in one environment does not break the others. Production credentials should be available only to the production environment and a small number of people.
Name environments consistently everywhere: in Drush aliases, hostnames, the pipeline, and monitoring. Confusion between "stage", "staging", and "test" sounds trivial until someone runs a command against the wrong one.
How eWay structures Drupal environments
eWay provisions Dev, Test, Staging, and Production from infrastructure as code so they match by design, with Config Split and environment-specific settings for the differences that should exist. Deployments run through Git-based pipelines using Drush and Composer, promoting one artifact through each stage with peer review and automated checks. Production data is copied down sanitized, secrets live in a managed secrets store, and patches and releases are always validated outside production first.
What to include in a support ticket
- The severity you would assign, P1 to P4 (see severity levels and response times)
- Which environments are involved and what behaves differently between them
- For a refresh request: the source, the target, and anything that must not be overwritten
eWay customers can open a ticket in the support portal or email support@ewaycorp.com at any time. See how to request support for all the options. Related reading: Dev, Test, and Live environments and using Drush safely. More on our Drupal page.
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article