必须在容器启动前用模板替换将Docker环境变量注入config.user.inc.php,而非运行时调用getenv();需自定义entrypoint.sh配合envsubst或sed处理占位符,且MySQL 8.0还需额外配置认证插件。

phpMyAdmin config.inc.php 里不能直接用 $_ENV 或 getenv() 读取 Docker 环境变量
config.inc.php 是 PHP 配置文件,不是运行时脚本——它在 phpMyAdmin 启动前就被解析,此时 $_ENV 和 getenv() 多数为空或不可靠。Docker 环境变量不会自动注入到 PHP 配置上下文中。硬写 getenv('DB_HOST') 在 $cfg['Servers'][1]['host'] 里,大概率得到空字符串,导致登录页下拉列表消失或连接失败。
真正可行的路径只有一条:把环境变量值提前注入进 config 文件内容本身,而不是让 PHP 在运行时去读。
必须用启动前模板替换,比如 envsubst + docker-entrypoint.sh
Docker 官方镜像不支持原生环境变量插值,得自己加一层处理。核心是:在容器启动前,把 config.user.inc.php 模板里的占位符(如 %%DB_HOST%%)替换成真实值,再写入目标路径。
- 准备一个模板文件
config.user.inc.php.tpl,里面写:$cfg['Servers'][1]['host'] = '%%DB_HOST%%';<br>$cfg['Servers'][1]['port'] = %%DB_PORT%%;<br>$cfg['Servers'][1]['auth_type'] = 'cookie';
- 挂载该模板进容器,并在
docker run里加-e DB_HOST=db-dev -e DB_PORT=3306 - 自定义
entrypoint.sh,开头执行:envsubst < /tmp/config.user.inc.php.tpl > /etc/phpmyadmin/config.user.inc.php
- 确保挂载命令包含
-v $(pwd)/config.user.inc.php.tpl:/tmp/config.user.inc.php.tpl:ro
注意:envsubst 默认只替换 $VAR 和 ${VAR} 形式,若用 %%VAR%% 这类自定义占位符,得用 sed 替代,或先 export 变量再调 envsubst。
立即学习“PHP免费学习笔记(深入)”;
别信 PMA_HOSTS 或 PMA_ARBITRARY 环境变量能帮你动态填 IP
PMA_HOSTS 只控制登录页下拉菜单显示哪些 host 名字,不参与实际连接配置;PMA_ARBITRARY=1 允许用户手动输 host,但需要 $cfg['AllowArbitraryServer'] = true; 且存在安全风险(暴露任意地址输入框),和“环境变量动态填 IP”完全无关。
这两个变量都不影响 $cfg['Servers'] 数组的实际内容,更不会帮你把 DB_HOST 的值塞进数组里。依赖它们等于没配服务器。
混合 MySQL 5.7/8.0 时,环境变量还可能掩盖认证插件问题
假设你用 envsubst 把 %%DB_HOST%% 替换成了 mysql80,但没同步改用户认证方式:MySQL 8.0 默认用 caching_sha2_password,而 phpMyAdmin 4.9 的 mysqli 扩展不支持——结果就是登录页卡住、空白或跳回表单,错误日志里却看不到明确提示。
这时候查 SELECT user, host, plugin FROM mysql.user WHERE user='root'; 才是关键。环境变量只负责传 host,不负责修 plugin。
真正要动态适配,得在模板里也预留 %%DB_AUTH_PLUGIN%% 占位符,再配合 $cfg['Servers'][$i]['auth_plugin'] 字段(如果版本支持),否则只能人工干预每个实例的 MySQL 用户。



















