Cloud 7.01

Change Configurations

Understanding configuration sources, priority order, environment variables, env.php vs config.php, and configuration locking.

Exam Critical: Understanding configuration sources and their priority order is ESSENTIAL for the exam!

Configuration Management

mindmap root((Configuration Sources)) Priority Order 1 Environment Variables 2 app etc env php 3 app etc config php 4 Database 5 Module XML Environment Variables Highest priority CONFIG DEFAULT prefix CONFIG STORES prefix Per environment Auto redeploy config php Cross environment system default path Merged with env php env php Environment specific Merged with config php Runtime merge

Configuration Sources and Priority

Five Configuration Sources (Highest to Lowest Priority)

Priority Source Scope Overrides
1 (Highest) Environment Variables Per-environment, set in Project Web Interface All other sources
2 app/etc/env.php Environment-specific config.php, Database, Module XML
3 app/etc/config.php Cross-environment (all environments) Database, Module XML
4 Database Runtime configuration (core_config_data table) Module XML only
5 (Lowest) Module XML Default configuration (etc/config.xml) None (base defaults)

Priority Rule

Higher priority sources ALWAYS override lower priority sources. Environment Variables (1) override everything; Module XML (5) is overridden by everything.

1. Environment Variables (Highest Priority)

Using Environment Variables

Key Characteristics

  • Highest priority: Override ALL other configuration sources
  • Set in: Project Web Interface (with env: prefix)
  • Auto-redeploy: Environment is redeployed when variable added
  • Inheritance: Can allow child environments to inherit values
  • Locks configuration: Admin cannot change in Stores → Configuration

Syntax for All Stores

CONFIG__DEFAULT__CARRIERS__TABLERATE__ACTIVE
Breakdown:
  • CONFIG - Required prefix
  • DEFAULT - Scope (default/stores/websites)
  • CARRIERS__TABLERATE__ACTIVE - Configuration path (double underscore separates segments)

Syntax for Single Store

CONFIG__STORES__DEFAULT__CARRIERS__TABLERATE__ACTIVE
Store-Specific Configuration:
  • Use STORES scope
  • Use store code in place of DEFAULT
  • Example: CONFIG__STORES__UK_STORE__CARRIERS__TABLERATE__ACTIVE

How to Set Environment Variables

  1. Navigate to Project Web Interface
  2. Select environment
  3. Go to Variables tab
  4. Add variable with env: prefix
  5. Example: env:CONFIG__DEFAULT__CARRIERS__TABLERATE__ACTIVE = 1
  6. Save (environment auto-redeploys)

2. app/etc/env.php (Environment-Specific)

Environment Configuration File

Purpose

This file contains configuration that is specific to each environment.

Typical Contents:
  • Database connection details
  • Cache configuration (Redis, Varnish)
  • Queue configuration
  • Session configuration
  • Search engine configuration (Elasticsearch)
  • Admin URL
  • Crypt key

Example Configuration

return [
    'db' => [
        'connection' => [
            'default' => [
                'host' => 'localhost',
                'dbname' => 'magento',
                'username' => 'magento',
                'password' => 'password'
            ]
        ]
    ],
    'cache' => [
        'frontend' => [
            'default' => [
                'backend' => 'Cm_Cache_Backend_Redis',
                'backend_options' => [
                    'server' => 'redis',
                    'port' => '6379',
                    'database' => '0'
                ]
            ]
        ]
    ]
];

Important: Runtime Merge

app/etc/env.php and app/etc/config.php are merged together at runtime. They work as a single configuration source with env.php taking precedence.

3. app/etc/config.php (Cross-Environment)

Shared Configuration File

Purpose

This file contains information used across ALL environments.

Typical Contents:
  • Module list (enabled/disabled)
  • Store configuration (websites, stores, store views)
  • Themes configuration
  • Locale settings
  • System configuration (when dumped)

Configuration Path Format

All Stores:

Use system/default path:

'system' => [
    'default' => [
        'carriers' => [
            'tablerate' => [
                'active' => 1
            ]
        ]
    ]
]
Individual Store:

Use system/stores/[store_code]:

'system' => [
    'stores' => [
        'uk_store' => [
            'carriers' => [
                'tablerate' => [
                    'active' => 1
                ]
            ]
        ]
    ]
]

Configuration Locking

Configuration specified in app/etc/config.php is merged with app/etc/env.php. Values set here LOCK the configuration - admin cannot change them in Stores → Configuration.

4. Database (core_config_data)

Runtime Configuration Storage

Purpose

Stores configuration values set through admin panel in core_config_data table.

Table Structure:
  • scope - default, stores, websites
  • scope_id - ID of store/website (0 for default)
  • path - Configuration path (e.g., carriers/tablerate/active)
  • value - Configuration value

Example Query

SELECT * FROM core_config_data
WHERE path = 'carriers/tablerate/active'
AND scope = 'default'
AND scope_id = 0;

When Admin Changes are Saved

When admin changes configuration in Stores → Configuration, values are saved to core_config_data. These values have LOWER priority than env.php, config.php, and environment variables.

5. Module XML Configuration (Defaults)

Base Configuration Defaults

Purpose

Provides default configuration values in module's etc/config.xml file.

Can be overridden by:
  • Area-specific XML files (frontend, adminhtml, etc.)
  • Database values
  • app/etc/config.php values
  • app/etc/env.php values
  • Environment variables

Example: etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <carriers>
            <tablerate>
                <active>0</active>
                <title>Table Rate</title>
            </tablerate>
        </carriers>
    </default>
</config>

Configuration Locking Behavior

When Configuration is Locked

Locking Mechanism

When a Store Configuration value is overridden in environment variables, app/etc/env.php, or app/etc/config.php, the Magento admin is unable to change the value.

Visual Indicators:
  • Field is disabled/grayed out in admin panel
  • Tooltip shows "This configuration is locked"
  • Value cannot be modified through UI

Example: app:config:dump Effect

Critical: Running bin/magento app:config:dump effectively locks ALL Magento configuration because all values are now specified in app/etc/config.php.

After config:dump, admin users cannot change settings in Stores → Configuration!

Important Side Note: Encrypted Values

Don't Use Environment Variables for Encrypted Values

Critical Warning

Don't specify environment variables for encrypted store configuration values!

Why?
  • While it technically works, it creates problems
  • Different environments should have different encryption keys
  • Magento can't legibly decrypt value with wrong encryption key
  • Results in configuration errors and broken functionality
Examples of Encrypted Values:
  • Payment gateway credentials
  • API keys
  • Shipping account numbers
  • Third-party service passwords

Best Practice

For encrypted values, use environment-specific app/etc/env.php or set them directly in database per environment. Never share encrypted values across environments with different encryption keys.

Configuration Merge at Runtime

How env.php and config.php Merge

Runtime Merge Process

One critical thing to remember: app/etc/env.php and app/etc/config.php are merged together at runtime.

  1. Magento loads config.php (cross-environment)
  2. Magento loads env.php (environment-specific)
  3. Configurations are merged (env.php takes precedence for conflicts)
  4. Environment variables override both
  5. Result is single unified configuration

Example Merge Scenario

// config.php
'system' => [
    'default' => [
        'web' => [
            'unsecure' => ['base_url' => 'http://example.com/']
        ]
    ]
]

// env.php
'system' => [
    'default' => [
        'cache' => [
            'frontend' => [...]
        ]
    ]
]

// Result after merge (runtime)
'system' => [
    'default' => [
        'web' => [
            'unsecure' => ['base_url' => 'http://example.com/']
        ],
        'cache' => [
            'frontend' => [...]
        ]
    ]
]

Complete Priority Example

Configuration Priority in Action

Let's say we have carriers/tablerate/active configured in multiple places:

Source Value Set Will it Apply?
Module XML (etc/config.xml) 0 (disabled) No - Overridden
Database (core_config_data) 1 (enabled) No - Overridden
app/etc/config.php 0 (disabled) No - Overridden
app/etc/env.php 1 (enabled) No - Overridden
Environment Variable 0 (disabled) YES - Highest Priority!

Result

Table Rate shipping will be disabled (0) because environment variable has highest priority and sets it to 0, overriding all other sources.

Exam Tips

Key Points to Remember

  • Priority order (high to low): Environment Variables → env.php → config.php → Database → Module XML
  • Environment variables: Highest priority, override everything, set with CONFIG__ prefix
  • All stores syntax: CONFIG__DEFAULT__PATH__TO__CONFIG
  • Single store syntax: CONFIG__STORES__STORECODE__PATH__TO__CONFIG
  • Auto-redeploy: Adding environment variable triggers redeployment
  • Inheritance: Child environments can inherit parent environment variables
  • app/etc/env.php: Environment-specific configuration
  • app/etc/config.php: Cross-environment (all environments)
  • Runtime merge: env.php and config.php merged together at runtime
  • Configuration locking: Values in env.php/config.php/env vars lock admin UI
  • app:config:dump: Locks ALL configuration by moving to config.php
  • Encrypted values: DON'T use environment variables (different encryption keys cause problems)
  • Database: core_config_data table, lower priority than env.php/config.php
  • Module XML: Lowest priority, base defaults in etc/config.xml