Skip to main content

Environment-specific store configuration

We know that Magento's env.php file is used to store critical environmental configuration, like database connection info. But is there more that can be done with this file? Yes! Further utilization of the env.php file will make the life of any Magento developer MUCH easier.

Here's how.

Has this ever happened to you?

  • Forgetting what needs to be changed when syncing a database from a production to a non-production environment.
  • Test orders accidentally synced into a production ERP.
  • Search engines accidentally indexing test sites.
  • Google Analytics (or equivalent) accidentally tracking test sites.
  • Automated emails from a test site sent to real customers.
  • Carefully configured payment sandbox settings overwritten. (What a headache!)
  • Forgetting to reset services like Varnish / full page cache when migrating a project to a different environment.

Then you need environment-specific configuration!

What is environment-specific configuration?

Magento has thousands of store configuration settings. These are ordinarily found in Magento's backend under Store & Configuration. An important subset of these settings should be considered environment-specific. The list could change from project to project.

These are common settings that should be considered environment-specific:

  • Base URLs
  • Payment method settings (production vs. sandbox)
  • Integrations with external eCommerce systems (ERP, CRM, PIM)
  • Services that may differ from one environment to another (Varnish / full page cache, search engine)

Base URLs are the easiest way to understand the nature of environment-specific configuration. A Base URL is always different in every environment, from production to staging to multiple other test environments. An environment's URL is specific to that environment, not to the project codebase or database. What's more, we don't want a URL to accidentally migrate from one environment to another.
It's easy to prevent this!

How to properly handle environment-specific configuration

The Magento CLI gives us a great tool for properly setting environment-specific configuration. For instance, the following command would set Base URLs in the env.php file. (As opposed to the core_config_data table of the database.)

bin/magento config:set --lock-env web/secure/base_url"https://staging.site.com/"

After running this command, observe the result in the env.php file.

...

    'system' => [
        'default' => [
            'web' => [
                'secure' => [
                    'base_url' => 'https://staging.site.com/'
                ]
            ]
        ]
    ]

Magento has created a multidimensional PHP array to store the configuration value. This value will be loaded by Magento, overriding the setting in the core_config_data table.

The goal of the env.php file is to hold configuration in a given environment. (Note: env.php should NOT be tracked in a Git repository.) We move a lot of code from environment to environment as part of our change control processes (Git workflows). We also occasionally move databases from one environment to another.

Neither of those processes involves the env.php file. And that's a good thing! Configuration in the env.php file stays where it belongs, in its environment.

The great store configuration hierarchy

Magento gives us a hierarchy of different ways to set store configuration. The settings in Magento's admin can and should be overridden. Here are the levels of hierarchy from most to least specificity:

  • Environment variables - Environment variables of the form "CONFIG__DEFAULT__WEB__SECURE__BASE_URL" will be loaded into Magento configuration.
  • env.php - A file not tracked in the code repository. Appropriate for environment-specific store configuration.
  • config.php - A file tracked by the repository. Appropriate for store configuration that you would like to manage with code deployments instead of through Magento's admin. Versioned configuration! (Not appropriate for environment-specific store configuration.)
  • core_config_data table in the DB - When you save configuration from Magento's admin, it goes here.
  • config.xml - Located in a Magento module. If you have not made a configuration setting anywhere else, defaults defined by the module author are used.

If your projects only use Magento's admin / DB for setting store configuration, do yourself a favor and become familiar with the additional methods.

You'll be happy you did!

 

It's self-documenting!

A well-utilized env.php file reads like documentation for a project's environments. Read the following sample from an env.php file. What can be inferred?

...
    'system' => [
        'default' => [
            'web' => [
                'unsecure' => [
                    'base_url' => 'http://staging.site.com/'
                ],
                'secure' => [
                    'base_url' => 'https://staging.site.com/'
                ]
            ],
            'google' => [
                'analytics' => [
                    'active' => '0'
                ]
            ],
            'payment' => [
                'authnetcim' => [
                    'test' => '1',
                    'login' => '0:3:qcEsHnd32d3qd3qd3qhwvnbUvSvs8fRP2gS9FIq2DKk=',
                    'trans_key' =>
'0:3:AeeHEd3qdq3dq3eUHdx4qmgQvneiC7vaY6yX//+lSmqTjcWyfe3FbPq8=',
                    'client_key' => '33StDZdq3edq3q3edd3qecRbEY5t9t43pCk6f3A5HwrSX3b3M628bWAFn'
                ]
            ],
            'paypal' => [
                'wpp' => [
                    'sandbox_flag' => '1',
                    'api_username' => '0:3:hhzr3q43qdqd34ypN4UZUvaIqbwOWH14XeJuqlqsN2w8MBuZC3S67FKsQCfy28MkhUJNszcA==',
                    'api_password' => '0:3:ipdq334d334djDB/PWlP9QMBmmXA2vPMLRxW2h2N+0arBq/zmkmKZ+pRTSR4qBE=',
                    'api_signature' => '0:3:ZyDdq34dq43dq43w3q4dWn8bz0O8AaV71y9kKzVcXqDt5MTmJRik9hjfKq+oA0GKQcDBDwqj1tgOYBMLXE3MoeoZz9teT7tR1whIeJ6dZIW+q25'
                ],
                'general' => [
                    'business_account' => 'account@site.com'
                ]
            ],
            'catalog' => [
                'search' => [
                    'engine' => 'elasticsearch7',
                    'elasticsearch7_index_prefix' => 'mysite',
                    'elasticsearch7_server_hostname' => 'elasticsearch'
                ]
            ],
            'recaptcha_backend' => [
                'type_for' => [
                    'user_forgot_password' => null,
                    'user_login' => null
                ]
            ],
            'recaptcha_frontend' => [
                'type_for' => [
                    'contact' => null,
                    'customer_create' => null,
                    'customer_forgot_password' => null,
                    'customer_login' => null,
                    'newsletter' => null,
                    'product_review' => null,
                    'sendfriend' => null
                ]
            ],
            'system' => [
                'full_page_cache' => [
                    'caching_application' => '2' // Built in full page cache
                ]
            ]
        ]
    ],
,,,

Illuminating!
Here's what we now know:

  • It's a staging site!
  • Authorize.net and PayPal sandboxes are configured. Checkout can be fully tested.
  • No CAPTCHA friction when testing :)
  • Varnish is probably not present.

Avoid filling env.php (and config.php) with default or common configuration values. All values should tell a story of what is unique about this project / environment.

Template

Here's some example environment-specific configuration I find useful on every project.

What do you use?

bin/magento config:set --lock-env web/unsecure/base_url "http://site.com/"
bin/magento config:set --lock-env web/secure/base_url "https://site.com/" 

bin/magento config:set --lock-env catalog/search/engine elasticsearch7
bin/magento config:set --lock-env catalog/search/elasticsearch7_server_hostname elasticsearch 

bin/magento config:set --lock-env google/analytics/active 0
bin/magento config:set --lock-env analytics/subscription/enabled 0
bin/magento config:set --lock-env design/search_engine_robots/default_robots "NOINDEX,NOFOLLOW"

bin/magento config:set --lock-env system/full_page_cache/caching_application 1 // Built-in
bin/magento config:set --lock-env system/full_page_cache/caching_application 2 // Varnish

bin/magento config:set --lock-env paypal/wpp/sandbox_flag 1