The problem
How do I configure environment variables in Magento 2?
Magento does not have great support for environment variables, and their documention on this is misleading at best.
Once you reach a certain level of growth, you will need to break away from hosting your site on a single fragile legacy server.
This means switching to technology like docker and kubernetes, or even just load balancing AMIs. In all cases you need to find a way to configure your environments without passing around outdated env.php scripts.
The Solution
If we look at other frameworks, we can see a common solution in PHP is to utilise the native getenv() function.
For example, we can configure the database as follows by editing app/etc/env.php:
<?php
return [
'backend' => [
'frontName' => 'some_random_admin_123456'
],
// ...
'db' => [
'table_prefix' => '',
'connection' => [
'default' => [
'host' => getenv('MYSQL_HOST') . ':' . getenv('MYSQL_PORT'),
'dbname' => getenv('MYSQL_DATABASE'),
'username' => getenv('MYSQL_USERNAME'),
'password' => getenv('MYSQL_PASSWORD'),
// ...
],
],
],
// ...
];
They key part here to note is the use of getenv():
'dbname' => getenv('MYSQL_DATABASE'),
So if the environment variable MYSQL_DATABASE has been set then Magento will now utilise this.
Summary
Inside our docker container we can now set these by passing through environment variables like MYSQL_HOST, MYSQL_PORT, MYSQL_USERNAME and MYSQL_PASSWORD.
This allows us to commit our env.php into our repo, then configure our environment values on each environment separately. And most importantly, this let's us slowly drag Magento one step further into the future.