Better Env handling in Symfony 3.2 and 3.3
Two weeks ago, Symfony announced a new Dotenv component. I’m not sure if you know about it, but I’m sure you should!
Why? Let's take a deeper look at Environment Variables first. Environment Variables are variables used in the shell in order to configure the behavior of different processes. The most often used one is PATH. They can also be used to configure a lot of different programs and servers, including Apache, Docker etc.
Why are they important? If you read through the Twelve-Factor App methodology description you can notice that point III. Config tells you to store all configuration in Environment Variables. This is good for you as it allows to easily configure the app in a cloud-based production/staging/testing/... environment. If using Docker, it makes things easier too—you don't need to mount a config volume, and you don't need to rebuild the image to make small changes in configuration. You just change the variable and it works!
So, in Symfony 3.2 the runtime environment variables were introduced (New in Symfony 3.2: Runtime Environment Variables (Symfony Blog)). Before that, Symfony allowed to use Environment Variables in its configuration, but the values were loaded only once during cache warmup.
From Symfony 3.2 up, the Environment Variable value is always up to date, so if you change it, you do not need to clean the cache. If you write projects that are built with scalability in mind, this makes configuration a lot easier. All configuration variables can be passed using the Environment Variables. No need to clean the cache, rebuild container images, etc.
What about Dotenv? Bigger systems usually have more settings, sometimes a lot of them, and as it is quite easy to provide them with a cloud-based solution—those auto-generates Environment Variables. It might become hard to provide them manually in a local testing environment. You could obviously override the parameters.yml file, but from now on, you can also use the .env file.
The .env file is just a simple file, where you put your Environment Variables. You can easily configure Symfony to load the .env file, and you do not need to provide the values in any other way. The Dotenv component comes with Symfony 3.3, but you need to install and configure it manually.
It is very easy to make use of the Environment Variables in Symfony. You just need to include them in the parameters.yml (or even directly in config.yml):
parameters: | |
database_host: '%env(DB_HOST)%' |
Now you can provide the variable directly:
DB_HOST=localhost bin/console doctrine:schema:create
Or by using the .env file:
DB_HOST=localhost
In order to make this file work, you need to add the Dotenv component to your application:
composer require symfony/dotenv
and include it in your front-controllers (app_*.php, app.php and bin/console):
<?php | |
// add this | |
(new \Symfony\Component\Dotenv\Dotenv())->load(__DIR__.'/../.env'); | |
// before this line | |
$kernel = new AppKernel('dev', true); |
Then you can just run the command:
bin/console doctrine:schema:create
It’s also very easy to pass them from your Apache, Nginx, Rancher etc. configuration. The env() notation can also be used directly in config.yml files, so it makes parameters.yml unnecessary in some cases.
As you might have noticed, all the changes combined together make the parameters.yml file unnecessary.
Let me know if you make use of Environment Variables and what is your opinion on that topic.