必须挂载到 /etc/mysql/conf.d/ 目录下才能生效,因 MySQL 官方镜像仅按序加载 /etc/mysql/mysql.conf.d/mysqld.cnf 和 /etc/mysql/conf.d/*.cnf,忽略 /etc/mysql/my.cnf;挂错路径会导致启动失败或配置不生效。

挂载自定义 my.cnf 到 /etc/mysql/conf.d/ 才生效,直接挂到 /etc/mysql/my.cnf 会被忽略——这是最常导致容器启动失败或配置不生效的根本原因。
为什么不能挂载到 /etc/mysql/my.cnf
MySQL 官方镜像(如 mysql:8.0、mysql:5.7)压根不读取顶层的 /etc/mysql/my.cnf。它的加载逻辑是:先读内置的 /etc/mysql/mysql.conf.d/mysqld.cnf,再按字母序加载 /etc/mysql/conf.d/*.cnf。挂载到 /etc/mysql/my.cnf 不仅无效,还可能干扰初始化流程,引发 Can't start server: Bind on unix socket: Permission denied 或 Unknown variable 'character-set-server' 等错误。
常见错误现象包括:
- 容器反复重启,
docker logs里看不到 MySQL 启动成功日志 - 连接后发现字符集仍是
latin1,show variables like 'character_set_server';返回值没变 - 执行
select @@max_connections;仍为默认值 151,说明max_connections未生效
正确的挂载路径与文件命名
必须把自定义配置文件(比如叫 my-custom.cnf)挂载到容器内 /etc/mysql/conf.d/ 目录下,且后缀必须是 .cnf:
- ✅ 正确:
docker run -v ./my.cnf:/etc/mysql/conf.d/my.cnf:ro - ❌ 错误:
-v ./my.cnf:/etc/mysql/my.cnf(被忽略) - ⚠️ 风险:
-v ./conf:/etc/mysql/conf.d(整目录挂载易引入.DS_Store或~$config.cnf等隐藏文件,MySQL 会尝试加载并报错)
文件权限需为 644,确保容器内 mysql 用户可读;加 :ro 是稳妥做法,防止运行时被意外覆盖。
配置文件内容必须满足的硬性条件
只写 [mysqld] 段,其他段([client]、[mysql])在容器内基本不生效,写了反而可能干扰调试。以下三项是底线,缺一不可:
-
skip-host-cache和skip-name-resolve:不加会导致启动卡在 DNS 解析,日志出现getaddrinfo failed或长时间无响应 -
character-set-server = utf8mb4:否则客户端连上后仍可能乱码,尤其存 emoji 或中文时
典型有效片段:
[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci skip-host-cache skip-name-resolve 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 路径必须指向容器内已挂载的日志目录(如 /var/log/mysql),否则启动报 Failed to open log file。
修改后必须重启容器,无法动态重载
MySQL 容器内进程不支持 mysqladmin reload 或 SIGHUP。哪怕你用 docker cp 替换了容器里的 /etc/mysql/conf.d/my.cnf,也必须执行 docker restart <container_name></container_name> 才能生效。
容易被忽略的点是:很多人以为改完配置文件、docker exec 进去手动 service mysql restart 就行了——但官方镜像没装 systemd 或 init.d 脚本,该命令大概率失败。唯一可靠方式就是 docker restart。











