Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
Environment variables to pass in global settings/configurations are a thing:
- Most hosters have some sort of support for them and expose the DB settings as such, for example
https://github.com/pantheon-systems/drops-8/blob/master/sites/default/settings.pantheon.php#L39
- It really explitely defined to be environment specific.
- Many systems have
.env
files to share those.
Usecases
- Override config variables: client IDs for 3rd party services etc, different site name per environment (staging-git-branch-name)
- Set
Settings
values, they seems to be our version of environment variables - container parameters, see https://symfony.com/doc/current/configuration/external_parameters.html#e...
Pro/Cons
- Hosters support it
- Its an industry standard
- Its more secure - https://12factor.net/config
- There is some criticism on the security site of things: http://movingfast.io/articles/environment-variables-considered-harmful/ but I doubt this applied to Drupal, given we don't start subprocesses
- Its another way, but its a more consistent and would allow to drop
Settings
potentially - Making it fast is tricky: http://drupal.org/project/config_override provides a compiler step to make it possible
Questions
- How does the ideal system look like (Settings still exist in the future?)
- How do we deal with security:
- http://movingfast.io/articles/environment-variables-considered-harmful/
- Webservers might expose
.env
files
Comments
Comment #2
dawehnerComment #3
moshe weitzman CreditAttribution: moshe weitzman commentedAdded a Pro about security. It links to https://12factor.net/config
Comment #4
Wim LeersThanks for proposing this, @dawehner! Curious what people more knowledgeable than me wrt server security have to say :) I like the apparent simplicity!
Comment #5
dawehnerComment #6
dawehnerI added some blog post with some criticism.
Comment #7
mpdonadioHow crazy / insecure would be be to totally pull settings.php from environment, which can also handle overrides already?
Comment #8
shrop CreditAttribution: shrop at Mediacurrent commentedThis topic reminded me of this article I read a while back that speaks to security of env vars. It appears that a few people in the article have varying opinions, but worth knowing some considerations around this topic.
http://searchsecurity.techtarget.com/blog/Security-Bytes/Environment-var...
This one has some good tips on securing env vars:
http://blog.honeybadger.io/securing-environment-variables/
For this article already mentioned in the issue description, I would like to see documentation around better ways to mange keys and other "secrets" than placing them in env vars.
http://movingfast.io/articles/environment-variables-considered-harmful/
Comment #10
gdamjan CreditAttribution: gdamjan commentedI would also like to be able to specify a "DRUPAL_STATE" directory which is the only place that Drupal will be able to write things. Currently Drupal defaults to writing to sites, without an option to override that (except by using symlinks).
An environment variable would be the proper way to setup that config.
ps.
Drupal should also expect the directory to be empty when first started.
Comment #13
fagoyeah, I think adding some support for dotenv would be really helpful and make the project appearing to play nice with industry-standards.
We've been using dotenv driven configs for a while, via symfony/dotenv which is added during the compose autoloader. Having environment variable defaults, allowing custom sites.php overrides and finally having per-multi-site dotenv that is applied across PHP and shell scripts ends up a bit tricky.
The setup we ended up with is testable from our drupal-project and works fine, but I want to improve how multiple dotenv files are combined in future:
https://github.com/drunomics/drupal-project/blob/4.x/web/sites/example.c...
I think some standard patterns that map environment variables to Drupal db credentials, Settings and Config would be definitely helpful.
Comment #15
geerlingguy CreditAttribution: geerlingguy at Midwestern Mac, LLC commentedAdding some tags after DrupalCon Seattle BoF on containerized Drupal in production. This would be a major help in not requiring everyone to come up with their own solution to 'how do I get Drupal's settings from the environment' and make Drupal a better player in the 12-factor app ecosystem.
Comment #16
BerdirEnvironment variables are also almost always prefixed and specific to hosters, e.g. plaform.sh puts stuff inside PLATFORM_VARIABLES, as base64 encoded json.
It's trivial to add a bunch of lines to extract it from there, we use d8config and d8settings prefixes to put stuff in settings/config overrides for example. But generic support wouldn't benefit us as we don't control the environment variables directly.
Comment #17
geerlingguy CreditAttribution: geerlingguy at Midwestern Mac, LLC commented@Berdir - It would still be nice to have a common set, for anyone not using a hosting provider that is unable to provide the vars specific to Drupal. And it would help greatly for local environments as well, so all the Docker-based tools could just use the same set of env vars and a var like
DRUPAL_ENV=local
. (I think there's a separate issue to standardize support for Drupal 'environment' awareness though.)Comment #18
moshe weitzman CreditAttribution: moshe weitzman commentedThere is a standard of sorts the drupal-project. Could be improved and more widely used, of course. See https://github.com/drupal-composer/drupal-project/blob/8.x/.env.example
Comment #19
johnwebdev CreditAttribution: johnwebdev commentedWe should probably not use .env at least until we move Drupal in to a separate document root. But then again, it is more secure to store environment variables on the server configuration rather than on the application level. For development and testing purposes its fine.
+1 On better support.
+1 On prefixes.
Comment #20
fago>But generic support wouldn't benefit us as we don't control the environment variables directly.
Imo, if you are using proper hosting, you should be able to control them - it's the industry standard for handling per-environment things, as they name "environment variables" say :D With Drupal propagating workflows with staging environments etc. this kind of seems a no-brainer to support.
Speaking of platform.sh, that allows setting custom environment variables as well.
We've been also using dotenv a lot in our projects and have a dotenv loader setup in https://github.com/drunomics/drupal-project to help dotenv file management and making sure .env is loaded across shell scripts and php the same.
Anyway, I highly agree that env variales should be standardized. We've started doing this across projects with a few essential ones here
https://github.com/drunomics/phapp-cli#available-variables
and more recently a few more here: https://github.com/drunomics/multisite-request-matcher/
We also have some helper to ease switching environment modes: https://github.com/drunomics/drush-phapp-env-mode
But in the end, what you want to cover with environment variables and what can stay fixed in some settings.php, differs per project. So having some optional variable support would be the way, e.g. something like
DRUPAL_ENV = {{ NAME }} (local,dev,prod, ..)
DRUPAL_ENV_MODE = production|development
which ideally are enforced to be set by code, and then optional ones for loading config like
DRUPAL_SETTINGS_{{ NAME }} = value
DRUPAL_CONFIG_{{ NAME }}___{{ KEY1 }}__{{ KEY2 }} = value
(only separators in env variables allowed is "_").
Comment #21
moshe weitzman CreditAttribution: moshe weitzman commentedThat pattern makes good sense to me.
Comment #22
fagooh, I almost forgot I also created https://www.drupal.org/project/services_env_parameter
Symfony has better, built-in support for environment variables in services.yml files, but would require some work in various places to make it work in Drupal, since Drupal's container builder is different to symfony's.
Comment #23
Fabianx CreditAttribution: Fabianx at Tag1 Consulting for American Federation of Teachers commented+1 to this issue in properly supporting .env.
We can even make this cleaner for true run-time changing of .env:
While currently the parameters in the parameter bag are included in the ContainerBuild definition [due to a Symfony build step], we could have Parameters that are of a NonIncludableVariable type.
Those variables would then be part of
$build_definition['variables']
and can be changed at run-time, which means that they are loaded fresh together with the container to whatever value is in the environment.It was one of the design goals of the Drupal's implementation of the Container [per alexpott' request at DrupalCon LA] to be able to specify parameters at run-time, but it has sadly not been used, yet.
Code - within likely a middleware - could then map from .env to container parameters.
Thanks, services_env_parameter looks interesting.
Comment #25
rominronin CreditAttribution: rominronin at Identum Communications GmbH commentedI came across this issue while looking for a twig function that could read environment variables for use in conditional statements eg. something like:
and just in general, I like the idea of being able to enable maintenance mode via .env (eg. MAINTENANCE_MODE = TRUE).