mysql容器启动失败主因是未设置非空mysql_root_password;数据持久化需挂载/var/lib/mysql;跨服务连接应使用服务名而非localhost;初始化脚本仅在空数据目录首次启动时执行。

MySQL 容器启动失败:检查 MYSQL_ROOT_PASSWORD 是否缺失
MySQL 官方镜像在容器启动时强制要求设置 MYSQL_ROOT_PASSWORD,否则会直接退出并打印错误:
error: database is uninitialized and password option is not specified。这不是警告,是硬性校验。
- 必须在
environment或.env文件中显式声明MYSQL_ROOT_PASSWORD - 若使用
MYSQL_PASSWORD(非 root)或仅设MYSQL_DATABASE,仍会失败 - 密码值不能为空字符串;设为
""也会触发相同错误
数据持久化失效:volumes 路径未映射到 MySQL 数据目录
MySQL 默认将数据写入 /var/lib/mysql,但很多人只挂载了自定义路径(如 ./mysql-data:/data),导致容器重启后数据丢失——因为 MySQL 根本没用这个路径。
- 正确写法是:
./mysql-data:/var/lib/mysql - 宿主机目录需有可写权限;Linux 下建议先
mkdir -p ./mysql-data && chown -R 999:999 ./mysql-data(MySQL 容器默认以 UID 999 运行) - 首次启动后,
/var/lib/mysql下会出现ibdata1、mysql等目录,这才是真实数据落盘位置
应用连接超时:Docker 内部网络与端口暴露配置不匹配
本地应用连不上容器内 MySQL,常见原因是混淆了 ports 和容器间通信机制。外部访问(如本机 Navicat)需要 ports,但同一 docker-compose.yml 中的其他服务(如 Python Web 应用)应直连服务名 + 默认 3306 端口,无需映射。
- 错误示例:用
localhost:3307从 Flask 容器连 MySQL —— 这实际连的是 Flask 自己的 localhost,不是 MySQL 容器 - 正确方式:Flask 的数据库 URL 设为
mysql://root:pass@mysql:3306/myapp,其中mysql是docker-compose.yml中服务的service name -
ports: ["3307:3306"]仅用于本机调试;生产环境建议不暴露端口,靠内部网络通信
初始化 SQL 执行失败:docker-entrypoint-initdb.d 脚本未生效
把 .sql 或 .sh 放进 ./init:/docker-entrypoint-initdb.d 后没执行,大概率是因为容器已初始化过数据目录——MySQL 只在空数据目录(即首次启动)时才运行该目录下的脚本。
- 确认
./mysql-data是空的;若有残留,删掉再重试 - SQL 文件必须以
.sql结尾,且权限为 644;.sh需有执行权限(755)并以#!/bin/bash开头 - 脚本内不要用
USE mydb,而应在连接串或语句中显式指定库名;初始化阶段默认库是mysql,非你声明的MYSQL_DATABASE
MYSQL_ROOT_PASSWORD 就无效了——它只作用于初始化阶段。










