---
title: "Configuring environments"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:environment-configuration@main"
source: "Administration/Deployment/EnvironmentStages/Configuration/Index.rst"
rendered: "2026-10-11T16:25:05+00:00"
---

# Configuring environments {#environment-configuration}

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](https://docs.typo3.org/permalink/t3coreapi:application-context@main) (`Development`,
`Production`).

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

**\<project-root>/.env**

```bash
# 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
[System configuration files](https://docs.typo3.org/permalink/t3coreapi:configuration-files@main)). The PHP code
for this could look like:

**config/system/additional.php**

```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:

-   [Password policies](https://docs.typo3.org/permalink/t3coreapi:password-policies@main)
-   [Configuration](https://docs.typo3.org/permalink/t3coreapi:error-handling-configuration@main)
-   [MAIL settings](https://docs.typo3.org/permalink/t3coreapi:typo3confvars-mail@main)
-   [encryptionKey](https://docs.typo3.org/permalink/t3coreapi:typo3confvars-sys-encryptionkey@main)
-   [Securing the Install Tool](https://docs.typo3.org/permalink/t3coreapi:security-install-tool@main)
-   Settings, tokens and URLs to additional services (Redis, Solr, third-party systems, ...)

> [!NOTE]
> The URL of your environment must be configured through
> [site configuration](https://docs.typo3.org/permalink/t3coreapi:sitehandling@main) variables, and those can
> actually refer to environment variables as outlined in
> [Using environment variables in the site configuration](https://docs.typo3.org/permalink/t3coreapi:sitehandling-using-env-vars@main).

The following sections describe this implementation process in depth.

## .env / dotenv files {#environment-dotenv}

A central advantage of `.env` files is that environment variables can also
be set in [Console commands (CLI)](https://docs.typo3.org/permalink/t3coreapi:cli-mode@main) 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/](https://github.com/symfony/dotenv/) or
[https://github.com/vlucas/phpdotenv/](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
<?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
<?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-connector {#environment-helhum-dotenv}

You can also use [https://github.com/helhum/dotenv-connector/](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`](../../../../Configuration/Typo3ConfVars/Index.md#file-project-config-system-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 {#environment-phpconfig}

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
<?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
<?php

defined('TYPO3') or die();

require __DIR__ . '/environment.php';

```

You can move such a file to a special `Shared/Data/` directory
(see [Deploying TYPO3](https://docs.typo3.org/permalink/t3coreapi:deploytypo3@main)), as long as you take care the file is
outside your public web root directory scope.

The file [`additional.php`](../../../../Configuration/Typo3ConfVars/Index.md#file-project-config-system-additional-php) can still contain custom changes that shall
be applied to every environment of yours, and that is not managed through
[`settings.php`](../../../../Configuration/Typo3ConfVars/Index.md#file-project-config-system-settings-php).

> [!TIP]
> **Hint**
>
> The file [`settings.php`](../../../../Configuration/Typo3ConfVars/Index.md#file-project-config-system-settings-php) is used by TYPO3 to store changes made through
> the GUI of the backend. [`additional.php`](../../../../Configuration/Typo3ConfVars/Index.md#file-project-config-system-additional-php) always has the higher
> priority, so configuration values there will overwrite the GUI configuration.

## Best practices for managing multiple environments {#multi-environment-best-practices}

TYPO3 projects often go through various stages, such as local development, integration, staging, and production.

For an overview of typical environment workflows, stable product promotion strategies, and team collaboration best practices,
refer to the following chapters:

> [!NOTE]
> **See also**
>
> -   [Multi-stage environment workflow](https://docs.typo3.org/permalink/t3coreapi:multi-stage-environment-workflow@main)
> -   [Synchronizing database content](https://docs.typo3.org/permalink/t3coreapi:multi-stage-environment-database-management@main)
> -   [Synchronizing user-uploaded files](https://docs.typo3.org/permalink/t3coreapi:multi-stage-environment-user-upload-management@main)
