Docker Compose启动MySQL后执行init.sql报文件不存在或访问拒绝问题
MySQL容器启动后自动执行init.sql的解决方案
核心问题原因
你的原有配置存在两个底层错误:
- volumes配置的路径映射中冒号前多了多余空格,导致本地目录和容器内目录映射失败,所以会提示找不到
/var/initdb/init.sql - 自定义的command直接覆盖了MySQL镜像默认的启动命令,容器根本没有启动MySQL服务,直接执行mysql客户端命令,就算路径、密码配置正确也会连接失败
方案1:仅首次初始化执行脚本(推荐)
MySQL官方镜像原生支持自动初始化逻辑:容器第一次启动、数据目录未初始化时,会自动执行/docker-entrypoint-initdb.d/目录下的所有.sql/.sql.gz/.sh文件,无需自定义command。
修改后的Docker Compose配置如下:
services: mysqldb: container_name: mysql image: mysql restart: always ports: - "3306:3306" volumes: - /mysql-schema:/var/schema - /init:/docker-entrypoint-initdb.d # 直接将本地init目录映射到镜像默认的初始化目录即可 environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_USER=a12nserver - MYSQL_PASSWORD=password - MYSQL_DATABASE=a12nserver networks: - MY_network
只要你的本地/init目录下存放了init.sql,容器首次启动时会自动执行该脚本。
方案2:每次容器启动都执行init.sql
如果需要每次启动容器都重新执行init.sql,可以自定义启动脚本,等待MySQL完全启动后再执行脚本:
- 在本地
/init目录下新建start.sh,写入以下内容:
#!/bin/bash # 后台启动MySQL服务 docker-entrypoint.sh mysqld & # 循环等待MySQL启动完成 until mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "SELECT 1" > /dev/null 2>&1 do sleep 2 done # 执行初始化脚本 mysql -u root -p"$MYSQL_ROOT_PASSWORD" a12nserver < /var/initdb/init.sql # 前台驻留进程避免容器退出 wait
- 给脚本添加执行权限:
chmod +x /init/start.sh - 修改Docker Compose配置,指定自定义启动命令:
services: mysqldb: container_name: mysql image: mysql restart: always ports: - "3306:3306" volumes: - /mysql-schema:/var/schema - /init:/var/initdb command: sh -c "/var/initdb/start.sh" environment: - MYSQL_ROOT_PASSWORD=password - MYSQL_USER=a12nserver - MYSQL_PASSWORD=password - MYSQL_DATABASE=a12nserver networks: - MY_network
补充说明
之前密码报错的原因是-p参数后没有直接传入密码,触发了交互式输入密码的逻辑,非交互式场景下可以直接用mysql -u root -p${MYSQL_ROOT_PASSWORD}的格式传递密码,也可以通过MYSQL_PWD环境变量传递密码避免明文展示。
内容的提问来源于stack exchange,提问作者Gary
相关产品推荐
相关产品推荐

