How to Organize Configuration Files
Warning: You are browsing the documentation for Symfony 3.x, which is no longer maintained.
Read the updated version of this page for Symfony 7.1 (the current stable version).
The default Symfony Standard Edition defines three
execution environments called
dev
, prod
and test
. An environment represents a way to
execute the same codebase with different configurations.
In order to select the configuration file to load for each environment, Symfony
executes the registerContainerConfiguration()
method of the AppKernel
class:
1 2 3 4 5 6 7 8 9 10 11 12 13
// app/AppKernel.php
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Kernel;
class AppKernel extends Kernel
{
// ...
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getProjectDir().'/app/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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
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
├─ ...
This default structure was chosen for its simplicity — one file per environment.
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
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
├─ ...
To make this work, change the code of the registerContainerConfiguration() method:
1 2 3 4 5 6 7 8 9 10 11 12 13
// app/AppKernel.php
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Kernel;
class AppKernel extends Kernel
{
// ...
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getProjectDir().'/app/config/'.$this->getEnvironment().'/config.yml');
}
}
Then, make sure that each config.yml
file loads the rest of the configuration
files, including the common files. For instance, this would be the imports
needed for the app/config/dev/config.yml
file:
1 2 3 4 5 6 7
# app/config/dev/config.yml
imports:
- { resource: '../common/config.yml' }
- { resource: 'parameters.yml' }
- { resource: 'security.yml' }
# ...
Note
Due to the way in which parameters are resolved, you cannot use them to build paths in imports dynamically. This means that something like the following doesn't work:
1 2 3
# app/config/config.yml
imports:
- { resource: '%kernel.project_dir%/app/parameters.yml' }
Semantic Configuration Files
A different organization strategy may be needed for complex applications with large configuration files. For instance, you could create one file per bundle and several files to define all application services:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
your-project/
├─ app/
│ ├─ ...
│ └─ 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
├─ ...
Again, change the code of the registerContainerConfiguration()
method to
make Symfony aware of the new file organization:
1 2 3 4 5 6 7 8 9 10 11 12 13
// app/AppKernel.php
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Kernel;
class AppKernel extends Kernel
{
// ...
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getProjectDir().'/app/config/environments/'.$this->getEnvironment().'.yml');
}
}
Following the same technique explained in the previous section, make sure to
import the appropriate configuration files from each main file (common.yml
,
dev.yml
and prod.yml
).
Advanced Techniques
Symfony loads configuration files using the Config component, 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
):
1 2 3 4 5 6 7 8
# app/config/config.yml
imports:
- { resource: 'parameters.yml' }
- { resource: 'services.xml' }
- { resource: 'security.yml' }
- { resource: 'legacy.php' }
# ...
Caution
The IniFileLoader
parses the file contents using the
parse_ini_file function. Therefore, you can only set
parameters to string values. Use one of the other loaders if you want
to use other data types (e.g. boolean, integer, etc.).
If you use any other configuration format, you have to define your own loader class extending it from FileLoader. 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 configurations from databases or web services.
Global Configuration Files
Some system administrators may prefer to store sensitive parameters in files
outside the project directory. Imagine that the database credentials for your
website are stored in the /etc/sites/mysite.com/parameters.yml
file. Loading
this file is as simple as indicating the full file path when importing it from
any other configuration file:
1 2 3 4 5 6
# 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 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:
1 2 3 4 5 6
# app/config/config.yml
imports:
- { resource: 'parameters.yml' }
- { resource: '/etc/sites/mysite.com/parameters.yml', ignore_errors: true }
# ...
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 "How to Override Symfony's default Directory Structure".