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

1次阅读

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

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

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 下会出现 ibdata1mysql 等目录,这才是真实数据落盘位置

应用连接超时:docker 内部网络与端口暴露配置不匹配

本地应用连不上容器内 MySQL,常见原因是混淆了 ports 和容器间通信机制。外部访问(如本机 navicat)需要 ports,但同一 docker-compose.yml 中的其他服务(如 Python Web 应用)应直连服务名 + 默认 3306 端口,无需映射。

  • 错误示例:用 localhost:3307flask 容器连 MySQL —— 这实际连的是 Flask 自己的 localhost,不是 MySQL 容器
  • 正确方式:Flask 的数据库 URL 设为 mysql://root:pass@mysql:3306/myapp,其中 mysqldocker-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 就无效了——它只作用于初始化阶段。

text=ZqhQzanResources