Drupalwoo ☉

Set up environment indicators for Drupal

Environment indicators make the active Drupal environment visible before an editor creates content, changes configuration or approves a release. A clear Development, Staging or Production label belongs in the toolbar and should survive page caching. On a Drupal site, this small distinction prevents test data reaching customers, a module update running twice, or a production setting being overwritten by a local export.

The strongest setup separates code, database, uploaded files, search index and cron state. All three environments can run the same Git revision, yet each needs its own database credentials and storage location. Environment indicators should describe that separation, not create it. If staging shares a database with production, an indicator alone cannot make the arrangement safe.

Australian teams often spread developers and content editors across Sydney, Melbourne, Brisbane and Perth. Clear hostnames such as dev.example.com.au, staging.example.com.au and www.example.com.au make support requests easier to route and reduce the chance that somebody edits the wrong copy. These cities also use different time settings: Sydney and Melbourne observe daylight saving, while Brisbane and Perth do not.

Australian retailers and service organisations may handle customer names, email addresses, telephone numbers and delivery histories in Drupal. Where the Australian Privacy Act 1988 and Australian Privacy Principles apply, copy personal information only into authorised systems and use synthetic records for development. Australian data centres are available, but local hosting does not by itself satisfy privacy obligations; access, encryption, retention and processor agreements still matter.

Separate the three Drupal environments

Give each environment a precise purpose. Development supports feature work, experimentation and rapid feedback. Staging reproduces production closely enough to test content, modules, redirects and third-party integrations. Production serves the public website and real customers. The names should remain consistent in Drupal, deployment scripts, documentation and team conversations so “staging” cannot be mistaken for “testing” on a developer’s machine.

Use separate databases, uploaded-file directories and credentials for every environment. A suitable local setup might use DDEV, Lando or containers, while staging and production run on separate infrastructure. Keep secrets in environment variables or a deployment secret store, not in Git. The same codebase can be deployed to all three locations, provided each installation receives environment-specific settings during the release process.

Treat hostnames and time zones as part of the environment definition. A 4 pm Sydney handover can arrive at 1 pm in Perth during Western Standard Time, although daylight saving can temporarily alter the difference. Set Drupal’s default time zone with a PHP-compatible value such as Australia/Sydney, Australia/Brisbane or Australia/Perth, and test dates near daylight-saving transitions as well as ordinary release dates.

Install and configure the indicator

Install the maintained Environment contrib project that matches your Drupal major version. For a release packaged as drupal/environment, run composer require drupal/environment --with-all-dependencies and enable it with drush en environment -y. Some releases separate the switcher and toolbar badge into related projects, commonly using the environment_indicator machine name. Follow the compatible project’s dependency instructions and avoid forcing an older contrib release onto a newer Drupal version.

Configure the environments through the module’s administration interface, usually found under the Development section of Drupal configuration. Add the environment name, hostname and base URL for each system. Configure the toolbar badge with unmistakable wording, such as “Development — local data”, “Staging — test data only” and “Production”. Colour can provide an additional warning, but the text must remain understandable to people who cannot distinguish the colours.

Limit the environment switcher to internal destinations. Development and staging may offer links between one another when the module supports a cookie or query-string switcher, but production should never appear as a switch target. The indicator should also render correctly when full-page or reverse-proxy caching is enabled; otherwise different users could receive a cached badge for the wrong environment.

The following baseline keeps each environment’s purpose and safeguards visible:

Environment Primary purpose Access Data and indexing Typical hostname
Development Feature work and debugging Developers and authorised contractors Synthetic data; search indexing disabled dev.example.com.au
Staging Release rehearsal and approval Editors, testers and clients through protected access Sanitised data; noindex enforced staging.example.com.au
Production Public service and live content Public visitors and authorised staff Live data; search indexing enabled www.example.com.au

After saving the configuration, open the site in a private browser window on every hostname. Confirm that the correct badge appears, that the switch links lead only to permitted environments and that a shared cache does not mix the badge with another installation’s pages.

Connect settings to each environment

Keep shared Drupal configuration under version control, but isolate values that must differ. Site email addresses, contact details, payment gateways, analytics accounts, search credentials and API keys commonly need different values in each environment. Environment-specific settings can live in settings.local.php, which should remain outside Git, or be supplied through deployment variables. The indicator then gives editors a visible warning while the configuration prevents one environment from sending another environment’s data.

A practical deployment pipeline builds the same commit, installs dependencies, applies database updates, imports approved configuration and clears Drupal’s cache. For example, a continuous-integration job might run drush updatedb -y, drush config:import -y and drush cr against staging before promotion. Review configuration changes rather than importing an unreviewed export. Core updates, module configuration and custom code can have different risk levels and need separate deployment stages.

Environment definitions also need deliberate handling. If they are stored as Drupal configuration, deploy equivalent settings to all environments while retaining each hostname’s unique URL and access rules. If the module reads from server variables, set those values during deployment instead of editing settings.php by hand on the server. Document the expected value for each hostname and make the deployment fail when a required variable is missing.

Search indexing, scheduled cron jobs and file storage must follow the same separation. Run indexing only in production, and prevent staging search crawlers from discovering the site. Give each environment its own cron schedule or deliberately disable unnecessary jobs. A team relying on an arvo handover in Microsoft Teams or Slack can include the active hostname in deployment messages, the pull-request status and the release checklist so the destination is unmistakable.

Guard non-production environments

Protect development and staging at the edge as well as inside Drupal. Use VPN access, an IP allow list or HTTP basic authentication where appropriate. Drupal access control alone is insufficient because a cached page, password-reset endpoint or API request may be reachable before a user reaches the login form. Apply strong administrator passwords, multi-factor authentication for privileged staff and least-privilege roles to sensitive systems.

A staging site may contain a login form for integration testing, so its warning must be plain and prominent. A published login warning example illustrates how much users rely on wording that appears before credentials are entered; apply the same clarity to a banner reading “Staging — test data only”, rather than a vague “Test” label.

Send a X-Robots-Tag: noindex, nofollow response header from non-production hosts and make sure the generated robots.txt file does not invite crawlers. Restrict staging search indexing in Drupal as a second safeguard. Also disable public registration, password-reset emails, live payment workflows and outbound notifications unless they have been deliberately configured for the test environment.

Never place production database dumps, customer exports or live API credentials in a lower environment. Generate representative records for Australian testing, including Australian dollar prices, GST-inclusive totals, delivery postcodes and local contact details. Review any imported data before access is granted, remove it when the test is finished and keep audit logs of who accessed it.

Test and verify the production release

Test the indicator in ordinary and private browser sessions, on desktop and mobile layouts, and across all supported environments. Visit the homepage, an authenticated dashboard, cached pages and pages returned by an error handler. Verify that the environment name remains visible after login and that the switcher cannot expose production to unauthorised users. Check browser developer tools as well as the rendered page, since a correct toolbar icon may still be missing from the response returned to a client.

Run the full acceptance workflow against staging. Create and edit representative content, exercise multilingual paths if used, submit a form and test queued email. Confirm that absolute URLs point to the correct hostname, redirects remain within the expected environment and analytics or tag managers do not record staging activity as production traffic. A test scheduled for 8 March 2026 should also display the correct Australian date and time on each relevant server.

Promote the tested release through the deployment pipeline rather than copying files manually between servers. After deployment, check HTTP responses, Drupal’s status report, recent log messages, cron execution and search indexing. Remove staging credentials from production configuration, confirm that the production indicator displays the live label and ensure no environment-switch links appear publicly. A verified indicator then becomes a dependable part of every release, giving the whole Drupal team a simple visual check before content or configuration reaches customers.