mysql 8.0 官方镜像不读取 /etc/mysql/my.cnf,仅自动加载 /etc/mysql/conf.d/ 和 /etc/mysql/mysql.conf.d/ 下的 .cnf 文件;挂载必须用 -v /host/conf:/etc/mysql/conf.d,文件需以 .cnf 结尾、含 [mysqld] 段,且权限设为 644、属主匹配 uid 999。

直接挂载 my.cnf 到 /etc/mysql/my.cnf 会失效 —— MySQL 8.0 官方镜像默认只加载 /etc/mysql/conf.d/ 和 /etc/mysql/mysql.conf.d/ 下的 .cnf 文件,不读取根配置文件路径。
为什么 my.cnf 挂载到 /etc/mysql/my.cnf 不生效
MySQL 8.0 容器启动时执行的是 docker-entrypoint.sh,它会显式调用 mysqld --defaults-file=/etc/mysql/my.cnf 吗?不会。实际行为是:mysqld 默认按顺序读取多个路径,但官方镜像已将入口脚本硬编码为优先扫描 /etc/mysql/conf.d/*.cnf。即使你挂载了 /etc/mysql/my.cnf,只要里面没有 [mysqld] 段且未显式指定 --defaults-file,它就被忽略。
常见现象:docker logs mysql 显示 unknown variable 'lower_case_table_names=1' 或字符集没生效,基本就是配置没被加载。
- MySQL 8.0 官方镜像的配置加载逻辑固定,不支持覆盖
/etc/mysql/my.cnf主文件 -
/etc/mysql/conf.d/是唯一被无条件扫描的自定义配置目录(.cnf后缀) - 挂载单个
my.cnf到非标准路径(如/etc/mysql/my.cnf)需额外加--defaults-file参数,但会绕过 entrypoint 初始化逻辑,风险高
docker run 必须用 -v /host/conf:/etc/mysql/conf.d
这是最稳妥、被所有文档验证过的挂载方式。宿主机上的配置文件必须放在 /etc/mysql/conf.d/ 目录下,且以 .cnf 结尾(如 custom.cnf),MySQL 启动时自动合并加载。
实操建议:
- 在宿主机创建目录:
mkdir -p /mydata/mysql/conf.d - 写入配置文件:
/mydata/mysql/conf.d/custom.cnf,内容必须含[mysqld]段 - 启动命令中挂载:
-v /mydata/mysql/conf.d:/etc/mysql/conf.d(注意不是/etc/mysql) - 不要给文件起名
my.cnf—— 官方镜像自带!includedir /etc/mysql/conf.d/,重名可能导致解析冲突
配置文件里 lower_case_table_names=1 只能首次初始化时生效
这个参数影响数据字典底层存储,MySQL 8.0 要求它必须在 mysqld 第一次初始化 datadir 时就设定。如果容器已运行过、/var/lib/mysql 目录非空,再改配置并重启,MySQL 会直接拒绝启动,并报错:Cannot set lower_case_table_names = 1 with innodb_file_per_table = 1 或类似提示。
解决办法只有两个:
- 删掉宿主机挂载的
/mydata/mysql/data目录(确认无重要数据!),再重启容器 - 若已有数据,不能设
lower_case_table_names=1—— 这是硬限制,不是权限或路径问题 - 生产环境务必在第一次
docker run前就写好该配置,后续不可变更
挂载后权限不对导致容器启动失败
MySQL 容器内进程以 UID 999(mysql 用户)运行,如果宿主机上 /mydata/mysql/conf.d/custom.cnf 所有者不是 UID 999 或权限太严(如 600),容器可能无法读取配置,表现为启动几秒后自动退出,docker logs mysql 空或只显示 Initializing database 就停住。
修复方法:
- 设置文件可读:
chmod 644 /mydata/mysql/conf.d/custom.cnf - 确保属主匹配(推荐):
chown 999:999 /mydata/mysql/conf.d/custom.cnf - 若用
docker-compose,可在volumes中加:ro或:rw控制读写,但不解决 UID 不匹配问题
真正容易被忽略的点是:配置文件是否被加载,不能只看容器是否 running,必须进容器执行 mysql -uroot -p -e "SHOW VARIABLES LIKE 'lower_case_table_names';" 或 mysqld --verbose --help | grep "Default options" 来确认路径和参数实际生效情况。挂载成功 ≠ 配置生效。











