env.php vs config.php no Magento 2 explicados
Dois arquivos em app/etc controlam como uma instalação do Magento 2 sobe: env.php e config.php. Os dois são arquivos PHP que retornam arrays, os dois podem conter configuração da loja e os dois são editados por comandos do bin/magento. A diferença entre eles decide o que vai para o Git, o que fica no servidor e por que alguns campos do admin aparecem acinzentados.
Este artigo explica o que cada arquivo contém no Magento 2.4.8, como funciona a precedência de configuração e os comandos que gerenciam os dois.
A versão curta
| config.php | env.php | |
|---|---|---|
| Finalidade | Configuração compartilhada da aplicação | Configuração específica do ambiente |
| No Git | Sim | Não |
| Conteúdo típico | Lista de módulos, scopes, temas, configurações compartilhadas | Banco, cache, sessões, queue, crypt key, mode |
| Igual em todos os servidores | Sim | Não |
Se um valor é igual em desenvolvimento, staging e produção, ele pertence ao config.php. Se muda por ambiente ou é um segredo, pertence ao env.php.
config.php
A lista de módulos
A parte mais importante do config.php é o array modules. Cada módulo tem uma entrada com 1 para habilitado ou 0 para desabilitado:
<?php
return [
'modules' => [
'Magento_Store' => 1,
'Magento_Catalog' => 1,
'Magento_TwoFactorAuth' => 1,
'Vendor_Shipping' => 1,
],
];
O module:enable e o module:disable editam esse array, e o setup:upgrade adiciona a ele os módulos recém-instalados. A ordem no arquivo reflete a ordem de carregamento resolvida a partir das declarações de sequence em cada module.xml. Faça commit desse arquivo sempre que ele mudar. Um módulo ausente do config.php em produção simplesmente não é carregado, o que é uma fonte comum dos problemas de "na minha máquina funciona".
Scopes, temas e configurações compartilhadas
O app:config:dump pode exportar mais coisas para o config.php:
bin/magento app:config:dump scopes themes
bin/magento app:config:dump system
scopes grava websites, store groups e store views. themes grava os temas registrados. Com isso no arquivo, o setup:static-content:deploy e o setup:di:compile podem rodar em um ambiente de build sem banco de dados, o que torna um build de CI possível. Veja o artigo sobre GitHub Actions para um build que depende disso.
system grava os valores de configuração da loja sob a chave system. Valores marcados como sensíveis ou específicos de ambiente são gravados no env.php. Cuidado com um dump completo em uma loja existente. Todo valor exportado fica travado no admin, o que pode surpreender quem administra a loja. Exportar só os paths específicos que você quer controlar pelo código costuma ser melhor, usando config:set --lock-config.
Quando o config.php muda no deploy, rode app:config:import para importar scopes e temas para o banco. O setup:upgrade também dispara a importação. O app:config:status diz se os arquivos e o banco estão sincronizados.
env.php
O env.php é escrito pelo setup:install e pelo setup:config:set. Um exemplo reduzido de um setup no estilo de produção:
<?php
return [
'backend' => [
'frontName' => 'admin_x7k2'
],
'crypt' => [
'key' => 'base64...'
],
'db' => [
'table_prefix' => '',
'connection' => [
'default' => [
'host' => 'db.internal',
'dbname' => 'magento',
'username' => 'magento',
'password' => 'secret',
'model' => 'mysql4',
'engine' => 'innodb',
'initStatements' => 'SET NAMES utf8;',
'active' => '1',
'driver_options' => [
1014 => false
]
]
]
],
'resource' => [
'default_setup' => [
'connection' => 'default'
]
],
'MAGE_MODE' => 'production',
'session' => [
'save' => 'redis',
'redis' => [
'host' => 'redis.internal',
'port' => '6379',
'database' => '2'
]
],
'cache' => [
'frontend' => [
'default' => [
'backend' => 'Magento\\Framework\\Cache\\Backend\\Redis',
'backend_options' => [
'server' => 'redis.internal',
'port' => '6379',
'database' => '0'
]
],
'page_cache' => [
'backend' => 'Magento\\Framework\\Cache\\Backend\\Redis',
'backend_options' => [
'server' => 'redis.internal',
'port' => '6379',
'database' => '1'
]
]
]
],
'cache_types' => [
'config' => 1,
'layout' => 1,
'block_html' => 1,
'full_page' => 1
],
'lock' => [
'provider' => 'db'
],
'directories' => [
'document_root_is_pub' => true
],
'x-frame-options' => 'SAMEORIGIN',
'http_cache_hosts' => [
[
'host' => 'varnish.internal',
'port' => '6081'
]
]
];
A lista de cache_types está encurtada aqui. Um arquivo real lista todos os cache types. Algumas chaves que vale conhecer:
- crypt/key: a chave de criptografia para valores sensíveis de configuração, credenciais de pagamento e tokens. Perdê-la significa que esses valores não podem mais ser descriptografados. Faça backup dela com o mesmo cuidado da senha do banco.
- backend/frontName: o caminho da URL do admin. Um valor diferente do padrão reduz ataques automatizados ao login do admin.
- MAGE_MODE: developer, default ou production, definido com
deploy:mode:set. - cache e session: onde caches e sessões são guardados. As configurações de Redis estão em Redis para cache e sessões.
- cache_types: quais caches estão habilitados. O
cache:enablee ocache:disableeditam isso. - queue e cron_consumers_runner: a conexão AMQP e como o cron inicia os consumers de queue.
- http_cache_hosts: os hosts do Varnish que recebem requisições de purge.
- lock: o lock provider, que importa quando o cron roda em mais de um servidor.
Prefira o setup:config:set a edições manuais quando existir uma opção. Ele valida a entrada e grava a estrutura certa. Edições manuais servem para chaves sem comando, mas um erro de sintaxe no env.php derruba o site inteiro, então confira com php -l app/etc/env.php antes de recarregar.
Precedência de configuração
A configuração da loja, os valores que você vê em Stores, Configuration no admin, pode vir de quatro lugares. Da maior para a menor prioridade:
- Variáveis de ambiente com nomes como
CONFIG__DEFAULT__WEB__SECURE__BASE_URL - A seção
systemdoenv.php - A seção
systemdoconfig.php - A tabela
core_config_datano banco
Um valor definido em qualquer um dos três primeiros aparece como travado no admin, com uma nota dizendo que está definido em um arquivo ou no ambiente. Editar a linha do banco não tem efeito enquanto existir um valor em arquivo, uma armadilha clássica de debug. Se uma mudança de configuração não pega, confira os arquivos primeiro.
O formato da variável de ambiente é CONFIG__ seguido do scope, de um código de scope opcional e do path, tudo em maiúsculas com dois underscores como separador. Para um valor no escopo de website: CONFIG__WEBSITES__BASE__PAYMENT__CHECKMO__ACTIVE. Essas variáveis precisam chegar aos processos do PHP-FPM e do CLI, o que normalmente significa defini-las na configuração do pool do PHP-FPM e no ambiente que roda o cron.
Gravando valores de configuração pela linha de comando
bin/magento config:set web/secure/base_url https://shop.example.com/
bin/magento config:set --lock-env web/secure/base_url https://shop.example.com/
bin/magento config:set --lock-config catalog/frontend/grid_per_page 24
bin/magento config:sensitive:set payment/some_method/api_key
- Sem flags, o valor vai para o banco, como se tivesse sido salvo no admin.
--lock-envgrava noenv.phpe trava o campo. Use para base URLs, hosts e qualquer coisa que muda por ambiente.--lock-configgrava noconfig.phpe trava o campo. Use para configurações que devem ser iguais em todo lugar e controladas pelo Git.config:sensitive:setgrava noenv.phpvalores declarados como sensíveis pelo módulo. Ele só aceita paths registrados como sensíveis ou específicos de ambiente.
Use --scope e --scope-code para valores de website ou store view.
Regras práticas
- Faça commit do
config.php, nunca doenv.php. Mantenha umenv.php.exampleou um script de provisionamento para que um ambiente novo possa ser criado sem adivinhação. - Guarde o
env.phpde produção em um gerenciador de segredos ou em um backup criptografado, separado do código e do dump do banco. - Trave em arquivos só o que realmente precisa ser travado. Quem administra a loja perde a possibilidade de alterar valores travados no admin.
- No deploy, mantenha o
env.phpem uma pasta shared com link para cada release, como descrito em deploys sem downtime. - Quando algo se comporta de forma diferente entre ambientes, compare as seções
systemdos dois arquivos e as variáveis de ambiente antes de olhar o código.
FAQ
O app/etc/env.php deve ir para o Git?
Não. Ele guarda senhas do banco, a chave de criptografia e hosts específicos do ambiente. Mantenha em cada servidor e fora do repositório. Já o config.php deve ir para o Git.
Por que uma configuração aparece acinzentada no admin do Magento?
Ela está definida no env.php, no config.php ou em uma variável de ambiente. Valores dessas fontes sobrescrevem o banco, então o admin os mostra como travados. Mude o arquivo ou a variável, não o campo do admin.
O que acontece se eu perder a crypt key do env.php?
Todo valor criptografado com ela, como credenciais de pagamento, chaves de API e tokens de integração, não pode mais ser descriptografado. Faça backup do env.php de forma segura, separado do código.
Qual a diferença entre config:set --lock-env e --lock-config?
--lock-env grava o valor no env.php, para configurações que diferem por ambiente. --lock-config grava no config.php, para configurações que devem ser iguais em todo lugar e ficar no controle de versão.
Atendo como freelancer em Magento e Adobe Commerce, incluindo deploy e gerenciamento de configuração. Se precisar de ajuda com isso, fale comigo.
Artigos relacionados
Guia de multi store e multi website no Magento 2
Como planejar e configurar multi website, multi store e store views no Magento 2: o que cada escopo controla, roteamento com Nginx, config por escopo e tudo no código.
Deploy do Magento 2 sem downtime em um único servidor
Um deploy sem downtime para o Magento 2.4 em um servidor: build numa pasta de release, compile fora do live, troca de symlink e rollback em segundos.
Shipping method customizado no Magento 2: crie um módulo de carrier
Como criar um shipping method customizado no Magento 2.4: config.xml, system.xml, um carrier model com collectRates, regras de frete grátis e APIs externas de tarifa.
Checklist de limpeza de malware no Magento 2 para lojistas
Checklist defensivo para uma loja Magento 2 hackeada: sinais de comprometimento, achar código injetado em arquivos e banco, rebuild limpo, novas credenciais e hardening.