Magento 2

Magento 2 Configuration Drift: How env.php Overrides Were Leaking into config.php

Frustrated developer reviewing unexpected git diff changes in Magento 2 config.php after setup:upgrade.
Frustrated developer reviewing unexpected git diff changes in Magento 2 config.php after setup:upgrade.

Understanding a Critical Magento 2 Configuration Bug: env.php Overrides and config.php Rewrites

As e-commerce migration experts at Shopping Mover, we frequently navigate the intricate landscape of Magento 2 configurations. A robust and predictable configuration management strategy is paramount for stable deployments, especially when dealing with multiple environments like development, staging, and production. Recently, a significant bug (GitHub Issue #41280) came to light, highlighting a critical flaw in how Magento 2 handled module states defined in app/etc/env.php, leading to unintended modifications in app/etc/config.php.

This issue, now resolved, underscores the importance of understanding Magento's configuration layers and the potential pitfalls that can arise from unexpected interactions. For developers, system administrators, and anyone involved in Magento deployments, this fix brings much-needed stability and predictability.

The Dual Nature of Magento 2 Configuration: config.php vs. env.php

Before diving into the bug, let's briefly revisit the intended roles of Magento 2's primary configuration files:

  • app/etc/config.php: This file contains the default, global configuration for your Magento instance, including the enabled/disabled state of modules. It is typically committed to version control and should remain consistent across all environments.
  • app/etc/env.php: This file is designed for environment-specific overrides. It holds sensitive data like database credentials, cache settings, and crucially, allows for module state adjustments that are unique to a particular environment (e.g., disabling an ERP integration module in a local development environment). This file should generally NOT be committed to version control.

The clear separation between these files is fundamental for maintaining clean deployments and ensuring that environment-specific settings do not pollute the core application configuration.

The Core Problem: Environment-Specific Overrides Becoming Permanent

The issue, meticulously reported by SamJUK, detailed a scenario where module states explicitly disabled or enabled in the environment-specific app/etc/env.php file were inadvertently written back into the version-controlled app/etc/config.php. This happened after executing common Magento CLI commands such as bin/magento setup:upgrade, bin/magento module:enable, or bin/magento module:disable.

Let's illustrate with the example from the GitHub issue:

  1. You have Magento_Csp enabled in your app/etc/config.php.
  2. You decide to disable it for a specific environment (e.g., development) by adding the following to your app/etc/env.php:
    // app/etc/env.php
    return [
    // ... other settings
    'modules' => [
    'Magento_Csp' => 0 // Disable CSP for this environment
    ]
    ];
  3. Running bin/magento module:status Magento_Csp correctly reports it as disabled.
  4. However, after executing bin/magento setup:upgrade, a subsequent git diff app/etc/config.php would reveal that app/etc/config.php had been modified to include 'Magento_Csp' => 0.

This behavior directly undermined the intended separation, causing environment-dependent changes to leak into the core configuration, leading to unwanted commits and configuration drift across environments.

Root Cause and Broader Impact

The issue's author precisely identified the technical root cause: the Installer::createModulesConfig() method was calling Reader::load() without a specific file key. This action caused Magento to merge the contents of both config.php and env.php, and then, critically, write this combined result back into config.php. This effectively promoted an environment-specific override into a global, committed change.

The implications extended beyond just setup:upgrade:

  • module:enable and module:disable: These commands also suffered from the same flaw. Disabling an unrelated module (e.g., Magento_Robots) would still trigger the rewrite, causing any env.php module overrides to appear in config.php alongside the intended change.
  • bin/magento setup:module:config:status: This command would incorrectly report the configuration as outdated for as long as any env.php module override existed. This was because it compared Reader::load(ConfigFilePool::APP_CONFIG) (the content of config.php) against Installer::getModulesConfig() (the merged result of config.php and env.php), which would never be equal.

This bug was particularly problematic for common deployment strategies where developers disable integration modules (like ERP, CRM, or payment gateways) in non-production environments using env.php to speed up development or avoid external dependencies. The workaround was a cumbersome manual restoration of config.php after every affected CLI command.

Why This Bug Was Critical for Developers and Operations

For any serious Magento project, especially those undergoing migrations or continuous development, this bug introduced significant headaches:

  • Version Control Integrity: Unwanted changes in config.php forced developers to either commit environment-specific settings (a bad practice) or constantly revert changes, leading to 'noise' in version control history.
  • Deployment Inconsistency: It made it harder to ensure that all environments were running on the exact same base configuration, increasing the risk of unexpected behavior.
  • Increased Manual Work: The need to manually restore config.php after routine commands added unnecessary overhead and potential for human error.
  • Misleading Status Reports: The `setup:module:config:status` command's incorrect reporting could lead to confusion and wasted debugging time.

Ultimately, this bug created a subtle but persistent source of configuration drift, undermining the reliability and efficiency of Magento development and deployment workflows.

The Resolution: A Step Towards Cleaner Deployments

The good news is that this critical issue has been addressed, as indicated by the 'Progress: done' label on the GitHub issue. The fix ensures that module states set in app/etc/env.php are no longer inadvertently written back into app/etc/config.php. This means:

  • Your config.php remains pristine and truly version-controlled.
  • Environment-specific overrides in env.php stay isolated, as intended.
  • Commands like setup:upgrade, module:enable, and module:disable will no longer cause unwanted modifications to your core configuration.
  • setup:module:config:status will provide accurate reports.

This resolution significantly improves the predictability and stability of Magento 2 deployments, allowing developers and operations teams to manage configurations with greater confidence.

Shopping Mover's Perspective: Best Practices for Magento Configuration

At Shopping Mover, we understand that robust configuration management is a cornerstone of successful e-commerce operations and seamless migrations. This bug highlights why it's crucial to:

  • Understand Configuration Layers: Always be aware of which configuration file (`config.php`, `env.php`, module-specific XML) governs which settings.
  • Maintain Strict Version Control: Only commit `config.php` to your repository, never `env.php`. Use deployment scripts to generate or copy `env.php` for each environment.
  • Stay Updated: Regularly apply Magento patches and upgrade to newer versions to benefit from critical bug fixes like this one.
  • Automate Deployments: Implement automated deployment pipelines that handle configuration generation and caching, minimizing manual intervention.

During complex Magento migrations, our experts at Shopping Mover meticulously review and optimize configuration settings to ensure a stable, high-performing target store. We leverage our deep understanding of Magento's architecture to prevent issues like configuration drift, ensuring your new platform is built on a solid, predictable foundation.

The fix for Issue #41280 is a testament to the ongoing efforts of the Magento community to refine and stabilize the platform. By staying informed and adopting best practices, you can ensure your Magento 2 store runs smoothly and efficiently.

Share:

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools