Configuring environments

A TYPO3 instance is often used in different contexts that can adapt to your custom needs:

  • Local development

  • Staging environment

  • Production environment

  • Feature preview environments

  • ...

These can be managed via the same installation by applying different values for configuration options.

The configuration options can be managed either by an .env file or just simple PHP files. Each environment would load the specific .env/PHP file, which is usually bound to an application context (Development, Production).

For example, using a .env file in your project root, you can define several variables:

<project-root>/.env
# Mail settings
TYPO3_MAIL_TRANSPORT="smtp"
TYPO3_MAIL_TRANSPORT_SMTP_SERVER="smtp.example.com:25"
TYPO3_MAIL_TRANSPORT_SMTP_USERNAME="info@example.com"
TYPO3_MAIL_TRANSPORT_SMTP_PASSWORD="verySafeAndSecretPassword0815!"

# Database settings
TYPO3_DB_DBNAME="typo3"
TYPO3_DB_HOST="db.example.com"
TYPO3_DB_PASSWORD="verySafeAndSecretPassword0815!"
TYPO3_DB_USER="typo3"

# Rootpath for files
TYPO3_BE_LOCKROOTPATH="/var/www/shared/files/"

The next step is to retrieve these values in the TYPO3 application bootstrap process. The best place for this is inside system/additional.php (see Configuration files). The PHP code for this could look like:

config/system/additional.php
<?php

defined('TYPO3') or die();

$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport']
    = $_ENV['TYPO3_MAIL_TRANSPORT'];
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_server']
    = $_ENV['TYPO3_MAIL_TRANSPORT_SMTP_SERVER'];
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_username']
    = $_ENV['TYPO3_MAIL_TRANSPORT_SMTP_USERNAME'];
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_password']
    = $_ENV['TYPO3_MAIL_TRANSPORT_SMTP_PASSWORD'];

$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname']
    = $_ENV['TYPO3_DB_DBNAME'];
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['host']
    = $_ENV['TYPO3_DB_HOST'];
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['password']
    = $_ENV['TYPO3_DB_PASSWORD'];
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['user']
    = $_ENV['TYPO3_DB_USER'];

$GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath'] = [
    $_ENV['TYPO3_BE_LOCKROOTPATH'],
];

Each environment would have its own .env file, which is only stored on the corresponding target system. The development environment file could be saved as .env.example or delivered as the default .env in your project.

It is not recommended to store the actual .env file in your version control system (e.g. Git), only an example without sensitive information. The main reason is that these files usually hold credentials or other sensitive information.

You should only store environment-specific configuration values in such a configuration file. Do not use this to manage all the TYPO3 configuration options. Examples of well-suited configuration options:

Note

The URL of your environment must be configured through site configuration variables, and those can actually refer to environment variables as outlined in Using environment variables in the site configuration.

The following sections describe this implementation process in depth.

.env / dotenv files

A central advantage of .env files is that environment variables can also be set in Console commands (CLI) CLI context or injected via Continuous Integration/Deployment (CI/CD) systems (GitLab/GitHub) or even webserver configuration. It is also helpful to have a central place for environment-specific configuration.

To let your TYPO3 configuration parse keys and values stored in such a file, you need a library like https://github.com/symfony/dotenv/ or https://github.com/vlucas/phpdotenv/, and parse it in your system/additional.php

You can require these libraries through Packagist/Composer.

Example for symfony/dotenv:

config/system/additional.php
<?php

use Symfony\Component\Dotenv\Dotenv;
use TYPO3\CMS\Core\Core\Environment;

$dotenv = new Dotenv();
$dotenv->load(Environment::getProjectPath() . '/.env');

Example for vlucas/phpdotenv:

config/system/additional.php
<?php

use Dotenv\Dotenv;
use TYPO3\CMS\Core\Core\Environment;

defined('TYPO3') or die();

$dotenv = Dotenv::createUnsafeImmutable(Environment::getProjectPath());
$dotenv->load();

Once this code has loaded the content from the .env file into $_ENV variables, you can access contents of the variables anywhere you need.

helhum/dotenv-connect

You can also use https://github.com/helhum/dotenv-connector/ (via the Packagist package helhum/dotenv-connector) to allow accessing $_ENV variables directly within the Composer autoload process.

This has two nice benefits:

  • You can even set the TYPO3_CONTEXT application context environment variable through an .env file, and no longer need to specify that in your webserver configuration (for example, via .htaccess or virtual host configuration).

  • You do not need to add and maintain such loading code to your additional.php file.

The drawback is that you will have an additional dependency on another package, and glue code that is outside of your own implementation.

Plain PHP configuration files

If the concept of requiring a specific file format and their loader dependencies seems like too much overhead for you, something similar can be achieved by including environment-specific PHP files.

For example, you can create a custom file like system/environment.php that will only be placed on your specific target server (and not be kept in your versioning control system).

config/system/environment.php
<?php

defined('TYPO3') or die();

$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport']
    = 'smtp';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_server']
    = 'smtp.example.com:25';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_username']
    = 'info@example.com';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_password']
    = 'verySafeAndSecretPassword0815!';

$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname']
    = 'typo3';
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['host']
    = 'db.example.com';
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['password']
    = 'verySafeAndSecretPassword0815!';
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['user']
    = 'typo3';

$GLOBALS['TYPO3_CONF_VARS']['BE']['lockRootPath'] = [
    '/var/www/shared/files/',
];

This file would also need to be loaded through the additional configuration workflow (which can be kept in your versioning control system):

config/system/additional.php
<?php

defined('TYPO3') or die();

require __DIR__ . '/environment.php';

Of course, you can move such a file to a special Shared/Data/ directory (see Deploying TYPO3), as long as you take care the file is outside your public web root directory scope.

The file additional.php can still contain custom changes that shall be applied to every environment of yours, and that is not managed through settings.php.

Hint

The file settings.php is used by TYPO3 to store changes made through the GUI of the backend. additional.php always has the higher priority, so configuration values there will overwrite the GUI configuration.