mysql在Docker Compose环境中集成部署示例

来源:这里教程网 时间:2026-02-28 20:52:32 作者:

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

相关推荐