Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • SensioLabs Professional services to help you with Symfony
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by SensioLabs
  1. Home
  2. Documentation
  3. Configuration
  4. How to Organize Configuration Files
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud

Table of Contents

  • Different Directories per Environment
  • Semantic Configuration Files
  • Advanced Techniques
    • Mix and Match Configuration Formats
    • Global Configuration Files

How to Organize Configuration Files

Edit this page

Warning: You are browsing the documentation for Symfony 2.7, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

How to Organize Configuration Files

The default Symfony Standard Edition defines three execution environments called dev, prod and test. An environment simply 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\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    // ...

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load($this->getRootDir().'/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
15
/
├─ 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 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
21
/
├─ 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 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\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    // ...

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load($this->getRootDir().'/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:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
# app/config/dev/config.yml
imports:
    - { resource: '../common/config.yml' }
    - { resource: 'parameters.yml' }
    - { resource: 'security.yml' }

# ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- app/config/dev/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <imports>
        <import resource="../common/config.xml" />
        <import resource="parameters.xml" />
        <import resource="security.xml" />
    </imports>

    <!-- ... -->
</container>
1
2
3
4
5
6
// app/config/dev/config.php
$loader->import('../common/config.php');
$loader->import('parameters.php');
$loader->import('security.php');

// ...

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:

  • YAML
  • XML
  • PHP
1
2
3
# app/config/config.yml
imports:
    - { resource: '%kernel.root_dir%/parameters.yml' }
1
2
3
4
5
6
7
8
9
10
11
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <imports>
        <import resource="%kernel.root_dir%/parameters.yml" />
    </imports>
</container>
1
2
// app/config/config.php
$loader->import('%kernel.root_dir%/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
24
/
├─ 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
├─ src/
├─ vendor/
└─ web/

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\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    // ...

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load($this->getRootDir().'/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):

  • YAML
  • XML
  • PHP
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' }

# ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <imports>
        <import resource="parameters.yml" />
        <import resource="services.xml" />
        <import resource="security.yml" />
        <import resource="legacy.php" />
    </imports>

    <!-- ... -->
</container>
1
2
3
4
5
6
7
// app/config/config.php
$loader->import('parameters.yml');
$loader->import('services.xml');
$loader->import('security.yml');
$loader->import('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:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
# app/config/config.yml
imports:
    - { resource: 'parameters.yml' }
    - { resource: '/etc/sites/mysite.com/parameters.yml' }

# ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <imports>
        <import resource="parameters.yml" />
        <import resource="/etc/sites/mysite.com/parameters.yml" />
    </imports>

    <!-- ... -->
</container>
1
2
3
4
5
// app/config/config.php
$loader->import('parameters.yml');
$loader->import('/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:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
# app/config/config.yml
imports:
    - { resource: 'parameters.yml' }
    - { resource: '/etc/sites/mysite.com/parameters.yml', ignore_errors: true }

# ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <imports>
        <import resource="parameters.yml" />
        <import resource="/etc/sites/mysite.com/parameters.yml" ignore-errors="true" />
    </imports>

    <!-- ... -->
</container>
1
2
3
4
5
// app/config/config.php
$loader->import('parameters.yml');
$loader->import('/etc/sites/mysite.com/parameters.yml', null, 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".

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    We stand with Ukraine.
    Version:
    Code consumes server resources. Blackfire tells you how

    Code consumes server resources. Blackfire tells you how

    Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

    Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

    Symfony footer

    ↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

    Avatar of cgonzalez, a Symfony contributor

    Thanks cgonzalez for being a Symfony contributor

    2 commits • 24 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • Symfony at a Glance
      • Symfony Components
      • Case Studies
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • SymfonyConnect
      • Support
      • How to be Involved
      • Code of Conduct
      • Events & Meetups
      • Projects using Symfony
      • Downloads Stats
      • Contributors
      • Backers
    • Blog

      • Events & Meetups
      • A week of symfony
      • Case studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Documentation
      • Living on the edge
      • Releases
      • Security Advisories
      • SymfonyInsight
      • Twig
      • SensioLabs
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Deployed on

    Follow Symfony

    Search by Algolia