必须挂载到 /etc/mysql/conf.d/ 而非 /etc/mysql/my.cnf,因官方镜像仅自动加载 conf.d/ 下 .cnf 文件;覆盖 my.cnf 会丢失 socket、pid-file 等关键路径导致启动失败,而 conf.d/ 支持安全叠加、按字母序加载且后加载参数覆盖先加载。

不能直接挂载到 /etc/mysql/my.cnf,必须挂载到 /etc/mysql/conf.d/ 目录下,且文件名必须以 .cnf 结尾。
为什么挂载到 /etc/mysql/conf.d/ 而不是 /etc/mysql/my.cnf
MySQL 官方镜像(如 mysql:8.0)在启动时按固定顺序加载配置:/etc/mysql/my.cnf → /etc/mysql/conf.d/*.cnf → /etc/mysql/mysql.conf.d/*.cnf。其中 /etc/mysql/my.cnf 是主入口,内置了 socket、pid-file、datadir 等关键路径声明;直接覆盖它会导致容器启动失败,日志中常见 Can't start server: Bind on unix socket: Permission denied 或 Unknown variable 'character-set-server'。
/etc/mysql/conf.d/ 是专为用户定制设计的目录:只叠加、不破坏,且按字母序加载所有 .cnf 文件,后加载的同名参数会覆盖先加载的。
- 挂载
my.cnf到/etc/mysql/conf.d/是允许的,但容易与主配置混淆,不推荐 - 若用
:ro挂载,可防止容器内意外写入 - 文件权限需为
644,确保容器内mysql用户可读
my-custom.cnf 文件内容怎么写才生效
只有 [mysqld] 段落会被 MySQL 启动逻辑读取;[client]、[mysql] 等段在容器内基本无效,写了不仅没用,还可能干扰调试。
不要使用 !includedir 或 !include 指令——Docker 镜像不支持运行时 include,会导致配置解析失败。
- 必须以
[mysqld]开头,例如:[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci max_connections=500 innodb_buffer_pool_size=1G slow_query_log=1 slow_query_log_file=/var/log/mysql/slow.log
- 路径类参数(如
slow_query_log_file)要指向容器内已存在或可写的目录,否则启动报错 - 想控制加载顺序?加数字前缀,比如
01-charset.cnf、02-performance.cnf
挂载方式与重启验证要点
挂载命令示例:docker run -d --name mysql8-custom -e MYSQL_ROOT_PASSWORD=secure123 -v ./my-custom.cnf:/etc/mysql/conf.d/my-custom.cnf:ro -p 3307:3306 mysql:8.0。
对已有容器,不能仅靠 docker restart 生效:Docker 不会重新挂载卷,必须 docker stop && docker rm 后重新 run;若用 docker-compose,改完 volumes 后需 docker-compose up -d --force-recreate。
- 验证是否生效:进入容器执行
mysql --verbose --help | grep "Default options",确认/etc/mysql/conf.d/my-custom.cnf在加载路径中 - 再执行
mysql -uroot -p -e "SHOW VARIABLES LIKE 'max_connections';",看输出值是否为你设置的数值 - 检查错误日志:
docker logs mysql8-custom 2>&1 | grep -i "unknown variable\|cannot start"
最容易被忽略的是:配置文件里写了 [client] 段,或用了 !include,或权限不是 644,或挂载路径写成 /etc/mysql/my.cnf —— 这四点任一出错,都会导致配置静默失效,而容器看似正常运行,实则参数全没加载。











