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_DATABASEMySQL 的 Docker Compose 集成真正卡点不在语法,而在对“初始化时机”“用户权限模型”“网络命名空间”的隐含假设。一旦容器跑起来,再改
MYSQL_ROOT_PASSWORD就无效了——它只作用于初始化阶段。
