挂载配置文件到 /etc/mysql/conf.d/ 才生效,官方 MySQL 镜像(8.0/5.7)不读 /etc/mysql/my.cnf;必须以 [mysqld] 开头,含 skip-host-cache 和 skip-name-resolve,并设 character-set-server=utf8mb4 与 default-authentication-plugin=mysql_native_password,改后须 docker restart。

挂载配置文件到 /etc/mysql/conf.d/ 才生效
官方 MySQL 镜像(mysql:8.0、mysql:5.7)根本不会读取 /etc/mysql/my.cnf 这个顶层配置文件。它只自动加载 /etc/mysql/conf.d/ 和 /etc/mysql/mysql.conf.d/ 下所有以 .cnf 结尾的文件。
直接 -v ./my.cnf:/etc/mysql/my.cnf 挂载是无效的——这是最常被踩的坑。
- 把自定义配置保存为
mysqld.cnf或custom.cnf,放在宿主机任意目录(比如./conf/mysqld.cnf) - 用
-v ./conf/mysqld.cnf:/etc/mysql/conf.d/mysqld.cnf:ro挂载(:ro防止容器内误改) - 文件内容必须以
[mysqld]开头,且语法合法(括号匹配、无中文标点、等号前后无多余空格)
skip-host-cache 和 skip-name-resolve 必须加
不加这两项,容器启动会卡在 DNS 解析阶段:日志反复出现 getaddrinfo failed,或长时间无输出后超时退出。
哪怕你只是想调 max_connections 或 sql_mode,也得先保这俩底线参数。
-
[mysqld]段开头就写这两行,顺序无关 - 它们的作用是跳过 DNS 反向解析,避免依赖宿主机或容器网络的 DNS 配置
- 即使你用
--network host或固定 IP,也建议保留——不是“可能出问题”,而是“大概率卡住”
字符集和认证插件必须配套设置
只在配置里写 character-set-server = utf8mb4 不够。MySQL 8.0 默认用 caching_sha2_password 插件,但旧版客户端(Navicat ≤ 12、SQLyog、某些 JDBC 驱动)不支持,会报错:Authentication plugin 'caching_sha2_password' cannot be loaded。
- 必须同时设
default-authentication-plugin = mysql_native_password - 如果已初始化过数据目录(
/var/lib/mysql非空),仅改配置不够,还需进容器执行:ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 验证是否生效:
docker exec -it <container_name> mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "SELECT plugin FROM mysql.user WHERE user='root';"</container_name>
改完必须 docker restart,不能 reload
容器内 MySQL 不支持 mysqladmin reload 或 SIGHUP 动态重载。挂载新配置后,docker exec 进去改文件、service mysql restart、甚至 kill -HUP 都无效。
唯一可靠方式就是重启整个容器:
docker restart <container_name></container_name>- 如果是
docker-compose管理的,用docker-compose restart mysql - 重启后检查生效:
docker exec -it <container_name> mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "SHOW VARIABLES LIKE 'max_connections';"</container_name>
真正容易被忽略的是:挂载路径权限和 SELinux 上下文——尤其在 CentOS/RHEL 主机上,:ro 挂载可能因上下文限制失败,需加 :z 或 :Z 后缀,或者临时 setenforce 0 排查。


















