管理员保存系统配置时出现 The configuration file has changed,或页面提示成功但 config.php、env.php 没有按预期更新。先明确:普通 Store 配置多数写数据库,只有被锁定、导出或部署管理的配置才涉及文件。不要直接给 app/etc 目录 777 权限。

确认文件在部署流程中的状态

stat app/etc/config.php app/etc/env.php
ls -l app/etc/config.php app/etc/env.php
git status --short app/etc/config.php app/etc/env.php
bin/magento app:config:status

如果 config.php 属于发布用户、PHP-FPM 只读,这是许多生产环境的正确设计。此时不应让后台任意改文件,而应通过配置部署流程提交变更。

数据库值、锁定值和环境变量分开看

bin/magento config:show web/secure/base_url
bin/magento config:show payment/checkmo/active
grep -n "web|payment" app/etc/config.php app/etc/env.php
env | grep -E '^CONFIG__|^MAGENTO_'

后台表单值可能被环境变量或文件覆盖。若某项被锁定,后台修改不是正确入口;需要在部署源中改值,再执行导入。不要为了“让后台能保存”删除所有锁定配置。

审查后再导入

bin/magento maintenance:enable
bin/magento app:config:import
bin/magento cache:clean config
bin/magento maintenance:disable

导入可能涉及模块启用状态和作用域配置。生产站不要把 app:config:dump 当成无害命令,它可能导出数据库配置并改变后台可编辑状态。

namei -l app/etc/config.php
ps -eo user,group,cmd | grep '[p]hp-fpm'
getfacl app/etc app/etc/config.php app/etc/env.php

单机可使用共同组权限;不可变发布应让文件随 release 切换,运行用户只读。修复标准是明确哪类配置由后台管理、哪类由代码与环境管理,并在下一次部署后仍保持一致。

保存前后的文件时间能揭示谁在竞争写入

连续记录 inode、mtime 和发布任务时间。如果后台保存期间部署脚本正好替换 release,表单基于旧配置提交就可能触发 changed 提示。把配置修改纳入发布队列,避免管理员后台写文件与 CI/CD 同时运行。

stat -c '%n inode=%i mtime=%y owner=%U:%G' app/etc/config.php app/etc/env.php
ps -ef | grep -E '[d]eploy|[c]omposer|app:config'

对共享 app/etc 的多节点站点,还要确认没有两套发布任务同时写同一文件。最好让每个 release 携带确定的 config.php,并只在切换版本时执行一次受控导入。