最常见原因是MySQL 8.0+默认认证插件改为caching_sha2_password,旧客户端不支持,报“Authentication plugin 'caching_sha2_password' cannot be loaded”;需在init.sql中显式指定mysql_native_password插件创建用户。

init.sql 为什么执行了但新用户连不上
最常见原因是 MySQL 8.0+ 默认认证插件从 mysql_native_password 改为 caching_sha2_password,而很多客户端(尤其是旧版 PHP、Python 的 mysql-connector-python 或某些 ORM)不支持该插件,连接时直接报 Access denied for user 或 Authentication plugin 'caching_sha2_password' cannot be loaded。
- 解决方法:在
init.sql中显式指定认证插件,例如:CREATE USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; - 若必须用
caching_sha2_password,需确保客户端驱动版本 ≥ 8.0.16(Python)或已启用allowPublicKeyRetrieval=true等兼容参数 - 别依赖
ALTER USER ... IDENTIFIED BY后续修改——初始化阶段用户尚未存在,该语句会失败
MYSQL_USER 环境变量为什么不能替代 init.sql
MYSQL_USER 和 MYSQL_PASSWORD 在官方镜像中仅对空数据目录生效,且行为受限:只建用户、只赋 ALL PRIVILEGES ON $MYSQL_DATABASE.*、host 固定为 '%'、不支持角色、不支持多库授权、无法控制权限粒度。
- 一旦挂载了已有 volume,整个初始化逻辑跳过,
MYSQL_USER完全失效 - 它不创建角色,也不执行
SET DEFAULT ROLE,哪怕你后续手动建角色,用户也无法继承 - 权限语句不可审计、不可复现——没法写进 Git,没法做 CI/CD 验证
- 真正可控的方式只有把所有权限逻辑写进
/docker-entrypoint-initdb.d/*.sql
init.sql 执行失败的典型现象与排查路径
脚本静默不执行或部分失败,往往不是语法错,而是执行上下文或时机问题。常见表现:容器启动成功但用户不存在、GRANT 报 Unknown database、FLUSH PRIVILEGES 被忽略。
-
init.sql只在/var/lib/mysql目录为空时运行——检查 volume 是否已有数据,用docker volume inspect确认 - SQL 文件编码必须是 UTF-8 无 BOM,否则可能被跳过(尤其 Windows 编辑后上传)
- 避免在脚本里用
IF NOT EXISTS判断库或用户——初始化阶段脚本只跑一次,判断无效;幂等性靠DROP USER IF EXISTS+CREATE USER组合实现 - 不要在
.sh初始化脚本里用mysql -u root -p$MYSQL_ROOT_PASSWORD——该环境变量在初始化阶段不可见,应改用mysql --socket=/var/run/mysqld/mysqld.sock -u root
host 写成 'localhost' 就连不上应用容器
Docker 默认 bridge 网络下,应用容器和 MySQL 容器处于不同网络命名空间,应用发请求时源 IP 是 bridge 网关地址(如 172.17.0.x),不是 localhost。MySQL 认证时匹配的是 user@host 元组,'app'@'localhost' 只允许容器内本地 socket 连接,对外部网络请求完全拒绝。
- 生产环境不要盲目用
'%',可限制为具体子网,例如'app'@'172.18.0.%'(对应自定义 Docker 网络) - 若应用与 MySQL 同属一个 compose 文件,可用服务名作为 host,此时
'app'@'app-network'不可行——MySQL 不解析 DNS 名,仍需用 IP 段或'%' -
SHOW GRANTS FOR 'app'@'%'必须在容器内执行验证,不能只看 SQL 文件写了什么
init.sql 里有一行语法错误,MySQL 仍会启动,只是后续语句不再执行,而日志里可能只有一行“Processing /docker-entrypoint-initdb.d/init.sql”带过。务必在启动后立刻验证用户是否存在、能否从应用容器连入、权限是否符合预期。


















