One of the best practice when developing a Symfony application is to make it
configurable via a parameters.yml
file. It contains information such as
the database name, the mailer hostname, and custom configuration parameters.
As those parameters can be different on your local machine, your testing
environment, your production servers, and even between developers working on
the same project, it is not recommended to store it in the project repository.
Instead, the repository should contain a paramaters.yml.dist
file with
sensible defaults that can be used as a good starting point for everyone.
Then, whenever a developer starts working on the project, the
parameters`.yml
file must be created by using the parameters.yml.dist
as a template. That works quite well, but whenever a new value is added to the
template, you must remember to update the main parameter file accordingly.
As of Symfony 2.3, the Standard Edition comes with a new bundle that automates
the tedious work. Whenever you run composer install
, a script creates the
parameters.yml
file if it does not exist and allows you to customize all
the values interactively. Moreover, if you use the --no-interaction
flag,
it will silently fallback to the default values.
Please remember that storing password or any other sensitive information in
the parameters.yml
file is not a good idea, and Symfony provides other
ways to do the same in a more secure way.
Good idea.
Does this bundle run on each composer install and detect that parameters.yml not sync anymore with .dist (assume that a config key has been added since last commit) and handle the new key? Same with removed keys?
Also, in your post, you're saying storing passwords in parameters.yml is not as good/safe we might think and that Sf provides other ways, could you add a link to more info, refs? I'd be curious to know.
Best
@guillaume Yes it does. The main reason I created it was precisely to update the yml file when new keys are added in the dist file. by default, it also removes old keys but this can be disabled
While this is one way to handle environment-local configuration, we have come up with another way, which I think, might be slightly more flexible:
We actually check in parameters.yml. It contains sensible defaults and placeholders for sensitive configuration (e.g. Amazon S3 Credentials, etc.). Then, we have an additional file parameters_local.yml, which contains configuration values that override those in parameters.yml. We achieved this by adding just a couple of lines in AppKernel.php.
This has quite a few advantages:
Maybe such an approach could be considered as an alternative to the proposed new feature? - or maybe not ^^ Just wanted to share :)
Best regards, Mike
@Mike You even don't have to change your AppKernel to do that. We also have a similar configuration to avoid repeating default parameters. For instance, you can simply add in your config.yml :
parameters_dist.yml
only contains (all) default parameters like db user/pass = root/root, and parameters_local.yml can overwrite everything. The ignore_errors=true allow us to ignore if file is missing (may be usefull for local env).This is handy for local/test/staging env, but of course, we almost redefine everything for prod ;)
"Please remember that storing password or any other sensitive information in the parameters.yml file is not a good idea, and Symfony provides other ways to do the same in a more secure way."
Is using env variables more secure ? Or what are the secure alternatives for keeping, let's say, db user/password instead of parameters.yml?
Thanks @christophe for your answer. I've added your bundle, it works like a charm.
What about my second question, the "more secure way to handle sensitive info" ? :)
Best
+1 for info or reference how to store password in a more secure way,
@guillaume: like @anton mentioned it, I think he's talking about env variables (SYMFONY__MY_PARAM), which are maintained by a root/sysadm user and not by the _www user (ie. not the same user which run the code, and neither the same directory).
We use the same solution than Mike, it's quite effective since you can end up with an empty "parameters_local.yml" if every default setting works for you.
The "more secure way to handle sensitive info" is explained in the following cookbook recipe:
http://symfony.com/doc/master/cookbook/configuration/external_parameters.html
wouldn’t parameters.dist.yml be the smarter choice for the filename, as it doesn’t break auto-highlight features of editors that are based on file extensions?
Good job guys. But I want to know more about "Symfony provides other ways to do the same in a more secure way." anyone having idea about this one ?
Best regards, Sanjay
Good feedback @Matthieu! I guess it was the ignore_errors that kept me from importing it in the config right away, I didn't know that one. I guess I'm going to change that to simplify our setup :)
why the bundle's name is not even mentioned?
We ran into an issue where a hosting environment we were using had the credentials and other information in environmental variables. When looking at it this is actually a good practice and can be done easily when spinning up EC2 instances as well.
The problem we had was having symfony use these environmental variables. I ended up writing up a bash script which would take the variables and populate the parameters.ini file; however, I wish I had time to make a cleaner solution. I could see having this new script allow you to specify the values while using --no-interaction. But more ideally would be a way to have symfony use the environmental variables in place of the parameters.ini file. Maybe a way of using %ENV.db_username% within parameters.ini
@Stephen Incenteev ParameterHandler (which is the library mentionned in the blog post) supports it (except it supports parameters.yml, not parameters.ini). See its readme: https://github.com/Incenteev/ParameterHandler/
This is Best