Introduction

When working with Contao, sooner or later you will encounter various files. There is config.yaml, parameters.yaml, then .env and .env.local. And somehow they all seem to have something to do with configuration.

But which file is responsible for what? What belongs where? And why are there so many different files?

In this article, you will learn what purpose the individual configuration files serve and how Contao processes them.

An overview of the most important configuration files

Contao takes care of most of the configuration for you by providing useful default values. You can override these defaults if necessary. Since Contao is a comprehensive application, it offers many configurable areas – but you only need to customise what is really relevant for your project.

config.yaml

Path: config/config.yaml

In principle, there is only one configuration file in Contao Managed Edition, namely config.yaml.

You can make all configurations directly in it and, in theory, you don't need to worry about the other files at all.

That's it, end of blog post – if it weren't for versioning!

Projects are usually versioned, mostly with Git, but for this issue it doesn't matter which version control software is used.

For the sake of simplicity, we will use Git as an example below.

As soon as you write database access data or API keys into your config.yaml and save them in your Git repository (‘commit’), you suddenly have sensitive data in your Git history. And the whole point of Git and similar tools is to store this information forever and never forget it. For security reasons, this is not a good idea.

The solution? Exactly, sensitive data goes into a different file and is then referenced in config.yaml via placeholders. That's basically all that parameters.yaml, .env and the like do. We'll come back to their peculiarities in a moment.

The config.yaml file contains the configuration of the Contao application. This file is not created automatically and you create it manually as needed.

Usage:

  • Different configurations for test and production environments are possible
  • Unlike parameters.yaml, .env and similar files, config.yaml is included in the version control software
  • This is where you configure the Contao application
  • You create the file manually when you need it

Helpful examples of entries in config.yaml:

  1. Enable indexing of protected pages:
contao:
    search:
        index_protected: true
  1. Configure central image sizes:
contao:
    image:
        sizes:
            header_image:
                width: 1920
                height: 600
                resizeMode: crop
  1. Various other Contao-specific settings such as crawler configuration, upload limits, or locales.

Useful console commands:

Display the default configuration for Contao:

php vendor/bin/contao-console config:dump-reference contao

Display the current configuration:

php vendor/bin/contao-console debug:config contao

parameters.yaml

Path: config/parameters.yaml

The parameters.yaml file has historical reasons and originates from older Contao versions. In the Contao Managed Edition, the parameters for the database connection were originally stored here. The Contao Installtool also accessed this file.

The file was created automatically during installation and looked like this after installation:

# This file has been auto-generated during installation
parameters:
    database_host: …
    database_port: …
    database_user: …
    database_password: …
    database_name: …
    secret: …

You could also store additional entries here, such as details for sending emails via SMTP or API keys for extensions, etc.

The parameters.yaml should never be committed to the Git repository, as this file contains sensitive access data. Database passwords that consist only of numbers or contain certain special characters must be enclosed in single quotes.

The parameters.yaml has been marked as obsolete since Contao 4.13. This means that it is still supported (also under Contao 5), but should no longer be used. Instead, you should switch to .env files.

.env und .env.local

Path: /.env and /.env.local

These two files are located in the main directory of your Contao installation, on the same level as the files and templates folders and the composer.json file.

When installing Contao via Contao Manager (from version 1.8 onwards), these two files are automatically generated and the database connection is stored there.

The env files contain so-called environment variables.

What are environment variables?

Environment variables are variables that can be defined at the operating system level, per user, or even per process. The big advantage: your application is then ready for operation in containers.

This is an established standard that applies not only to Contao and Symfony, but is used across platforms. The environment variables can even be changed at runtime, although this will not be relevant for most of us.

For operation on normal shared hosting, where you cannot set real environment variables, Contao provides the option of defining environment variables in an .env file. Contao then interprets these as if they were real environment variables.

Difference between .env and .env.local

The .env file:

  • Is committed to the Git repository and does NOT contain real values
  • Serves to document required environment variables
  • Shows example values and structure

The .env.local file:

  • Is NOT committed to the Git repository (belongs in .gitignore)
  • Contains real values that overwrite the values documented in .env
  • Sensitive data such as passwords and API keys
  • Developer-specific settings

The frequently configured environment variables for Contao in .env.local

APP_SECRET

The environment variable APP_SECRET is used for many use cases. From CSRF tokens to URL signing and much more. Several extensions also require a secret for their applications. This is a string that should be unique to your application. Changing this value invalidates all signed URIs and, for example, ‘Remember Me’ cookies. Depending on the extensions you use, you should check whether you are allowed to change this value. If, for example, it was incorrectly used for encryption, the decryption of the data will no longer work. In this case, it would be advisable to contact the developers of the extension and set a separate entry in .env.local (e.g. MY_EXTENSION_ENCRYPTION_KEY=...).

Recommendations:

  • The value should contain randomly selected characters, numbers and symbols
  • Recommended length: at least 32 characters
  • Only change this value regularly if it was used exclusively for transient information

Contao automatically generates the APP_SECRET if it does not exist when executing composer install.

DATABASE_URL

The database connection information is stored as the environment variable DATABASE_URL. It defines the user name, password, host name, port, and database name.

Format:

DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name"

Special characters in passwords must be adjusted using URL encoding. The @ character becomes %40, the # character becomes %23, and so on.

Handy: In the Contao documentation, you can conveniently generate this DATABASE_URL string!

MAILER_DSN

Here you can configure email delivery.

Format:

MAILER_DSN="smtp://user:password@smtp.example.com:587"

The same applies here: special characters in the password must be adjusted using URL encoding.

Define your own environment variables

You can define any variables you want and then reference them in config.yaml.

Example:

# .env
MYADMIN_EMAIL=admin@demo.de
# config/config.yaml
contao:
    localconfig:
        adminEmail: '%env(MYADMIN_EMAIL)%'

Which Contao version uses which files?

Contao 4.4

  • Based on Symfony 3
  • Directory structure: app/config/ instead of config/
  • Mainly parameters.yaml and config.yml
  • .env files: Initial experimental support
  • The Contao installation tool can only access parameters.yaml

Contao 4.9

  • Based on Symfony 4
  • .env files: Full support
  • parameters.yaml: Still supported
  • Database connection can be provided via config/parameters.yaml OR via .env

Contao 4.13

  • Based on Symfony 5
  • .env.local: Fully supported and recommended practice
  • Typically, you only need to adjust DATABASE_URL in .env.local
  • Contao Manager version 1.8 and higher can configure the database connection
  • However, the Manager only understands .env.local, not parameters.yaml

Contao 5.3

  • Based on Symfony 6
  • Fully migrated to .env files and config.yaml
  • parameters.yaml: Still supported, but should no longer be used

In what order are the files loaded?

Contao is based on Symfony and follows its configuration system. The loading order is important because later files overwrite earlier ones.

Environment variables (.env files)

The .env files are loaded in this order:

  1. System environment variables (highest priority, NEVER overwritten)
  2. .env.$APP_ENV.local (e.g. .env.prod.local, .env.dev.local)
  3. .env.$APP_ENV (e.g. .env.prod, .env.test)
  4. .env.local (local overrides, not in Git)
  5. .env (default values, committed in Git)

The .env must exist alongside the .env.local, otherwise the .env.local will be ignored. Even if the .env contains nothing. Symfony's DotEnv component never overwrites real system environment variables.

YAML configuration files

Contao automatically loads config_prod.yaml or config_dev.yaml, depending on the environment. If these are not available, config.yaml is loaded as a fallback.

The environment-specific files override the settings from config.yaml.

Priority hierarchy (simplified)

From highest to lowest priority:

  1. .env.local (your local settings, overrides everything else)
  2. .env (default values from the repository)
  3. config/config_prod.yaml or config/config_dev.yaml (environment-specific)
  4. config/config.yaml (fallback if no environment-specific file is available)
  5. config/parameters.yaml (obsolete, overwritten by .env files)

.env.local or parameters.yaml for the database connection?

A question that comes up time and time again: Where should I configure the database connection?

The answer: Basically, Contao doesn't care where the database connection is located.

HOWEVER: The Contao Manager can only adjust the database connection in .env.local. If the database connection is configured in both files, Contao uses the data from .env.local.

Recommendation: Choose one option. The best practice is clear: use .env.local.

Digression: File extension .yaml or .yml?

You may have noticed that some files are called .yaml and others .yml. Is there a difference?

The answer: No, there is no difference.

Both file extensions are valid and are treated equally by Contao and Symfony.

Background: In older operating systems, file extensions were limited to three letters, which is why .yml was often used. This is no longer an issue in current systems.

Recommendation: Use .yaml, the full extension.

Best practices for Contao

To help you know how to handle configuration files in the future, here are the most important best practices:

  1. From Contao 4.13+: Use .env and .env.local instead of parameters.yaml

  2. In .env.local: In 90% of all cases, only DATABASE_URL, APP_SECRET and MAILER_DSN

  3. Never commit to Git: .env.local, parameters.yaml, API keys or other passwords

  4. **Allowed via Git commit: ** config.yaml or .env (with placeholders)

  5. Legacy projects: In older Contao 4 projects, parameters.yaml may still be present. When migrating to newer versions, you should migrate to .env.local and delete parameters.yaml to avoid confusion.

Conclusion

The various configuration files in Contao have clear tasks. The parameters.yaml is historical and should no longer be used in new projects. Instead, use the .env and .env.local for environment variables such as database connections and secrets.

In principle, everything could be written directly into the config.yaml. However, for security reasons, sensitive data is outsourced and only referenced in config.yaml.

config.yaml is the right place for bundle configuration and application settings. It is committed to the repository, while .env.local remains local and is NEVER committed.

The loading order is important: later files overwrite earlier ones. .env.local has the highest priority for environment variables.

If you follow these basic rules, you will maintain an overview of your Contao configuration.

Do you have any questions about the configuration files? Or is there a specific scenario where you are unsure? Write it in the comments.

Add a comment

Please calculate 3 plus 2.