Per-environment settings
Goal: make one codebase behave correctly on every environment: the right values per environment, secrets handled safely, and PHP tuned where the platform allows it.
A Cloud Platform application runs the same codebase on every environment, so anything that must differ between Dev, Stage, and Prod has to come from outside the code. There are three surfaces for that: environment variables, the environment’s PHP settings, and conditional logic in settings.php.
What you’ll have when you’re done
Section titled “What you’ll have when you’re done”settings.phplogic that branches on the platform’s own environment variables.- Custom variables for your per-environment values, with secrets kept out of them.
- PHP settings tuned per environment where the platform allows it, defaults left alone elsewhere.
Prerequisites
Section titled “Prerequisites”- A Cloud Platform application and interface access (variables and PHP settings are set there)
- Ship code to environments, since
settings.phpchanges deploy like any code change
-
Branch on the platform’s environment variables
Section titled “Branch on the platform’s environment variables”Every environment exposes variables your code and drush commands can read. The ones you’ll actually branch on:
Variable What it holds AH_SITE_ENVIRONMENTThe environment name: dev,test,prod, oride. The environment labeled Stage is namedtest, so that is the value to compare againstAH_PRODUCTION/AH_NON_PRODUCTION1on the matching side, undefined on the otherAH_SITE_NAMESite group + environment (used to build absolute paths, e.g. in scheduled jobs) AH_SITE_GROUPThe site group / Unix user name AH_GIT_REF/AH_GIT_SHAThe deployed branch/tag name and exact commit hash, for logs and error trackers TEMPThe environment’s real temp directory ( /mnt/tmp/[site].[env]); use it instead of/tmp, which is small and fillsThe full table is in Using environment variables on docs.acquia.com. Typical use in
settings.php:if (getenv('AH_SITE_ENVIRONMENT') === 'prod') {$config['system.performance']['cache']['page']['max_age'] = 43200;}One ordering rule: Acquia injects platform configuration into
settings.phpvia its own include (the Acquia require line). Environment-variable logic goes after that include, or it can be clobbered by it. -
Define custom variables for your own values
Section titled “Define custom variables for your own values”For values you define yourself (an API URL, a feature flag), add custom environment variables per environment with acli:
Terminal window acli api:environments:variable-create myapp.dev --name='MY_VARIABLE' --value='the-value' --task-waitvariable-list,variable-update, andvariable-deletecover the rest of the lifecycle, each taking the same environment ID or alias. Read the value from PHP the way you read a platform one:getenv('MY_VARIABLE'). The Cloud UI has the same actions on the environment; see Creating custom environment variables on docs.acquia.com.Rules and quirks worth knowing before you rely on them:
- Names can’t start with
AHorACQUIA; no spaces, tabs, or quotes in names or values; 255-byte names, 5000-byte values, 100 KB total. - They are not a secrets store. Custom variables are unencrypted and can leak into Drupal watchdog logs. Acquia’s own guidance: don’t put SSL certificates, SSH keys, or login/API credentials in them. For secrets, use a file in the private file system read from
settings.php, and follow the credential-handling patterns in the auth guide.
Prefer a custom variable over committed config when the value genuinely differs per environment or shouldn’t live in git history; prefer committed configuration for everything else, so environments stay reproducible from the repository. When whole modules or configuration objects differ per environment rather than single values, that’s a job for a configuration split instead: see manage configuration.
- Names can’t start with
-
Tune PHP settings where the platform allows
Section titled “Tune PHP settings where the platform allows”acli api:environments:updatesets these per environment, one flag each, queuing a task that--task-waitblocks on:Terminal window acli api:environments:update myapp.dev --memory_limit='192' --task-wait- PHP version (
--lang_version) per environment. Update Dev or Stage first, verify there, then Prod. - PHP memory limit per process (
--memory_limit, default 128 MB). Note the split that surprises people: drush and other CLI commands get 512 MB regardless, which is why a memory-starved cron job may succeed via drush and fail via the web. See scheduled jobs. max_execution_time(--max_execution_time, default 300 seconds). Longer isn’t better: a request that needs more than a couple of minutes should become a scheduled job; on Cloud Next, web requests past 10 minutes can be interrupted by routine platform maintenance.- OPcache size, APCu size, interned-strings buffer, max input vars, max POST size, memcached memory (
--opcache,--apcu,--interned_strings_buffer,--max_input_vars,--max_post_size,--memcached_limit): advanced dials; leave defaults unless Acquia Support advises otherwise or you have measurements. Some upper limits depend on subscription tier; see Configuring PHP settings on docs.acquia.com.
What you can’t tune: anything at the MySQL server level (centrally managed), Varnish behavior (steered by response headers, not settings), and the web-server configuration itself.
- PHP version (
-
Override
Section titled “Override settings.php, including the database”settings.php, including the databaseAcquia injects database credentials through its own include; your
settings.phpnever hardcodes them, and after the include runs,$databasesis populated. To adjust the connection rather than define it, modify$databasesafter the include. The supported example: MySQL server variables can’t be changed globally, but can be set per session via connectioninit_commands:// After the Acquia require line.$databases['default']['default']['init_commands'] = ['isolation' => 'SET SESSION transaction_isolation="READ-COMMITTED"',];The same post-include block is where per-environment overrides of any Drupal setting live, guarded by
AH_SITE_ENVIRONMENTchecks as above. The full set of worked$databasescases (external databases, multisite variants) is in Overriding Drupal $databases settings on docs.acquia.com.
When something goes wrong
Section titled “When something goes wrong”A changed variable isn’t visible
existing SSH sessions don’t see updates (reconnect), and changing a variable re-provisions the environment’s pods, which takes a moment.
An override has no effect
check its position relative to the Acquia require line; platform injection runs in that include, and logic placed before it gets overwritten.
Works via drush, fails via the web (or vice versa)
remember the memory-limit split in step 3.
Next steps
Section titled “Next steps”- Run scheduled jobs: the other half of environment configuration, recurring work.
- Manage configuration: the Drupal configuration that travels in code, and how
settings.phpoverrides switch it per environment. - How caching works: why cache lifetime is a header concern, not a PHP setting.
- Diagnose problems: when a setting change is a guess, measure instead.
Was this page helpful?
What went wrong?
Still stuck? Contact Acquia Support (opens in a new tab)