-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[RFR] Added "How to Organize Configuration Files" cookbook #3885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
0520bf1
d861be3
2a32b23
4a87cfb
af5d478
da3e1d0
be414e0
68a7d2a
4241ee5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
.. index:: | ||
single: Configuration, Environments | ||
|
||
How to Organize Configuration Files | ||
=================================== | ||
|
||
The default Symfony2 Standard Edition defines three | ||
:doc:`execution environments </cookbook/configuration/environments>` called | ||
``dev``, ``prod``, and ``test``. An environment simply represents a way to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove the comma before |
||
execute the same codebase with different configuration. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [...] with different configurations. |
||
|
||
In order to select the configuration file to load for each environment, Symfony | ||
executes the ``registerContainerConfiguration()`` method of the ``AppKernel`` | ||
class:: | ||
|
||
// app/AppKernel.php | ||
class AppKernel extends Kernel | ||
{ | ||
// ... | ||
|
||
public function registerContainerConfiguration(LoaderInterface $loader) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Either a use statement for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same applies to the |
||
{ | ||
$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); | ||
} | ||
} | ||
|
||
This method loads the ``app/config/config_dev.yml`` file for the ``dev`` | ||
environment and so on. In turn, this file loads the common configuration file | ||
located at ``app/config/config.yml``. Therefore, the configuration files of the | ||
default Symfony Standard Edition follow this structure: | ||
|
||
.. code-block:: text | ||
|
||
<your-project>/ | ||
├─ app/ | ||
│ └─ config/ | ||
│ ├─ config.yml | ||
│ ├─ config_dev.yml | ||
│ ├─ config_prod.yml | ||
│ ├─ config_test.yml | ||
│ ├─ parameters.yml | ||
│ ├─ parameters.yml.dist | ||
│ ├─ routing.yml | ||
│ ├─ routing_dev.yml | ||
│ └─ security.yml | ||
├─ src/ | ||
├─ vendor/ | ||
└─ web/ | ||
|
||
This default structure was choosen for its simplicity — one file per environment. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
But as any other Symfony feature, you can customize it to better suit your needs. | ||
The following sections explain different ways to organize your configuration | ||
files. In order to simplify the examples, only the ``dev`` and ``prod`` | ||
environments are taken into account. | ||
|
||
Different Directories per Environment | ||
------------------------------------- | ||
|
||
Instead of suffixing the files with ``_dev`` and ``_prod``, this technique | ||
groups all the related configuration files under a directory with the same | ||
name as the environment: | ||
|
||
.. code-block:: text | ||
|
||
<your-project>/ | ||
├─ app/ | ||
│ └─ config/ | ||
│ ├─ common/ | ||
│ │ ├─ config.yml | ||
│ │ ├─ parameters.yml | ||
│ │ ├─ routing.yml | ||
│ │ └─ security.yml | ||
│ ├─ dev/ | ||
│ │ ├─ config.yml | ||
│ │ ├─ parameters.yml | ||
│ │ ├─ routing.yml | ||
│ │ └─ security.yml | ||
│ └─ prod/ | ||
│ ├─ config.yml | ||
│ ├─ parameters.yml | ||
│ ├─ routing.yml | ||
│ └─ security.yml | ||
├─ src/ | ||
├─ vendor/ | ||
└─ web/ | ||
|
||
To make it work, change the code of the ``registerContainerConfiguration()`` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "To make this work," sounds better for continuity perhaps? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also does the method needs to follow some formatting guidelines for method naming? |
||
method:: | ||
|
||
// app/AppKernel.php | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the notes about use statements at the code block above. |
||
class AppKernel extends Kernel | ||
{ | ||
// ... | ||
|
||
public function registerContainerConfiguration(LoaderInterface $loader) | ||
{ | ||
$loader->load(__DIR__.'/config/'.$this->getEnvironment().'/config.yml'); | ||
} | ||
} | ||
|
||
Then, make sure that each ``config.yml`` file loads the rest of the configuration | ||
files, including the common files: | ||
|
||
.. code-block:: yaml | ||
|
||
# app/config/dev/config.yml | ||
imports: | ||
- { resource: '../config.yml' } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should also include XML and PHP |
||
- { resource: 'parameters.yml' } | ||
- { resource: 'security.yml' } | ||
|
||
# ... | ||
|
||
# app/config/prod/config.yml | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I prefer to put this in 3 different code blocks |
||
imports: | ||
- { resource: '../config.yml' } | ||
- { resource: 'parameters.yml' } | ||
- { resource: 'security.yml' } | ||
|
||
# ... | ||
|
||
|
||
# app/config/common/config.yml | ||
imports: | ||
- { resource: 'parameters.yml' } | ||
- { resource: 'security.yml' } | ||
|
||
# ... | ||
|
||
|
||
Semantic Configuration Files | ||
---------------------------- | ||
|
||
A different organization strategy may be needed for complex applications with | ||
large configuration files. You could for instance create one file per bundle | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For instance, you could create one file per bundle [...] |
||
and several files to define all the application services: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove the |
||
|
||
.. code-block:: text | ||
|
||
<your-project>/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could just be / rather than as maybe it is understood already |
||
├─ app/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we could also remove the /'s since anything that lacks extension is a folder? although some executables lack extension There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think including the slash makes things easier to understand There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 For keeping the slash for readability reasons. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 as well. Not all files have an extension ( |
||
│ └─ config/ | ||
│ ├─ bundles/ | ||
│ │ ├─ bundle1.yml | ||
│ │ ├─ bundle2.yml | ||
│ │ ├─ ... | ||
│ │ └─ bundleN.yml | ||
│ ├─ environments/ | ||
│ │ ├─ common.yml | ||
│ │ ├─ dev.yml | ||
│ │ └─ prod.yml | ||
│ ├─ routing/ | ||
│ │ ├─ common.yml | ||
│ │ ├─ dev.yml | ||
│ │ └─ prod.yml | ||
│ └─ services/ | ||
│ ├─ frontend.yml | ||
│ ├─ backend.yml | ||
│ ├─ ... | ||
│ └─ security.yml | ||
├─ src/ | ||
├─ vendor/ | ||
└─ web/ | ||
|
||
Again, change the code of the ``registerContainerConfiguration()`` method to | ||
make Symfony aware of the new file organization:: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also add some information that the environment config files imports the correct bundle configurations |
||
|
||
// app/AppKernel.php | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same notes about the use statements. |
||
class AppKernel extends Kernel | ||
{ | ||
// ... | ||
|
||
public function registerContainerConfiguration(LoaderInterface $loader) | ||
{ | ||
$loader->load(__DIR__.'/config/environments/'.$this->getEnvironment().'.yml'); | ||
} | ||
} | ||
|
||
Advanced Tecniques | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Techniques |
||
------------------ | ||
|
||
Symfony loads configuration files using the ``Config component </components/config>``, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and should be |
||
which provides some advanced features. | ||
|
||
Mix and Match Configuration Formats | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Configuration files can import files defined with any other built-in configuration | ||
format (``.yml``, ``.xml``, ``.php``, ``.ini``): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should add a little warning about the ini loader ( #3431 ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also not sure we should add the dot in front of each option here |
||
|
||
.. code-block:: yaml | ||
|
||
# app/config/config.yml | ||
imports: | ||
- { resource: 'parameters.yml' } | ||
- { resource: 'services.xml' } | ||
- { resource: 'security.yml' } | ||
- { resource: 'legacy.php' } | ||
|
||
# ... | ||
|
||
If you use any other configuration format, you have to define your own loader | ||
class extending it from ``Symfony\Component\DependencyInjection\Loader\FileLoader``. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's use the |
||
When the configuration values are dynamic, you can use the PHP configuration | ||
file to execute your own logic. In addition, you can define your own services | ||
to load configuration from databases and web services. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe suggest here extending or implementing a particular interface or using the ClosureLoader. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [...] to load configurations [...] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [...] databases or web servers. |
||
|
||
Directory Loading | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does directory loading really works out of the box ? I don't see anything about it in the codebase. Are you using a thrid-party bundle for that ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stof you are right. Thanks for noticing this. I was confused by the resource loading of the Config component and the fact that this correctly works for loading routes defined as annotations in one or more controllers inside a bundle. I've just removed this section. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest you open a feature request on Symfony for this. It looks useful (in case you don't need to strictly control the order of loading) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @javiereguiluz, I did a PR about Directory Loading, if you want to take a look: symfony/symfony#11059 |
||
~~~~~~~~~~~~~~~~~ | ||
|
||
Splitting configuration into lots of smaller files can rapidly become cumbersome | ||
when importing those files from the main configuration file. Avoid these problems | ||
by loading an entire directory: | ||
|
||
.. code-block:: yaml | ||
|
||
# app/config/config.yml | ||
imports: | ||
- { resource: 'bundles/' } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
- { resource: 'services/' } | ||
|
||
# ... | ||
|
||
The Config component will look for recursively in the ``bundles/`` and ``services/`` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [...] will recursively look in the [...] |
||
directories and it will load any supported file format (``.yml``, ``.xml``, | ||
``.php``, ``.ini``). | ||
|
||
Global Configuration Files | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Some system administrators may prefer to store sensitive parameteres in global | ||
configuration files under the ``/etc`` directory. Imagine that the database | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer something like "[...] files outside the project directory." |
||
credentials for your website are stored in the ``/etc/sites/mysite.com/parameters.yml``. | ||
Loading this file is as simple as indicating the full file path when importing | ||
it from any other configuration file: | ||
|
||
.. code-block:: yaml | ||
|
||
# app/config/config.yml | ||
imports: | ||
- { resource: 'parameters.yml' } | ||
- { resource: '/etc/sites/mysite.com/parameters.yml' } | ||
|
||
# ... | ||
|
||
Most of the time, local developers won't have the same files that exist in the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [...] that exist on the [...] |
||
production servers. For that reason, the Config component provides the | ||
``ignore_errors`` option to silently discard errors when the loaded file | ||
doesn't exist: | ||
|
||
.. code-block:: yaml | ||
|
||
# app/config/config.yml | ||
imports: | ||
- { resource: 'parameters.yml' } | ||
- { resource: '/etc/sites/mysite.com/parameters.yml', ignore_errors: true } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be documented for other formats as well (using a configuration-block), given that it is the only place in the doc talking about it AFAIK (btw, thanks for making me discover this setting) |
||
|
||
# ... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a bit strange end of an article. You may want to add something like As you've seen, there are lots of ways to organize your configuration files. You
can choose one of these or even create your own custom way of organizing the
files. Don't feel limited by the standard edition that comes with Symfony. For even
more customization, see ":doc:`dir_structure`". |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,3 +12,4 @@ Configuration | |
pdo_session_storage | ||
apache_router | ||
web_server_configuration | ||
configuration_organization |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we want to refer people to this article in the "Environments" index, do we?