如何通过.sql脚本初始化MySQL Docker容器?
如何在Docker启动容器时运行SQL文件填充MySQL数据库
你之前的错误原因
- 没错,
php:8.1-apache镜像默认未安装MySQL客户端,所以会出现mysql: not found的报错。 - 更关键的是:构建PHP镜像阶段,MySQL容器还未启动,根本无法连接数据库执行SQL,因此这个思路从根源上不成立。数据库初始化逻辑应该放在MySQL容器中完成,而非PHP容器。
方案一:利用官方MySQL镜像的自动初始化机制(推荐)
官方MySQL镜像内置了初始化逻辑:当容器第一次启动且数据库未初始化时,会自动执行/docker-entrypoint-initdb.d目录下的所有.sql/.sql.gz/.sh文件。无需自定义镜像,仅修改docker-compose.yml即可:
- 将你的
DB_Setup.sql文件放到项目根目录(或单独的sql子目录)。 - 修改
docker-compose.yml中mysql服务的volumes配置,添加SQL文件的挂载:
version: '3' services: php: build: context: . dockerfile: Dockerfile volumes: - ./src:/var/www/ ports: - 8080:80 depends_on: - mysql mysql: image: mysql:latest environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mydatabase MYSQL_USER: user MYSQL_PASSWORD: userpassword volumes: - mysql_data:/var/lib/mysql # 挂载单个SQL文件到初始化目录 - ./DB_Setup.sql:/docker-entrypoint-initdb.d/DB_Setup.sql # 若有多个SQL文件,建议挂载整个目录:- ./sql:/docker-entrypoint-initdb.d/ volumes: mysql_data:
- 启动容器(如果之前已启动过MySQL容器,需先删除数据卷才能触发初始化):
# 彻底删除旧容器和数据卷 docker-compose down -v # 重新启动容器 docker-compose up -d
注意:
- 可在SQL文件开头添加
USE mydatabase;,确保语句在目标数据库执行。 - 只有数据库第一次初始化时(数据卷为空),脚本才会执行;后续重启容器不会重复执行。
方案二:自定义MySQL镜像
如果你需要把SQL文件打包进镜像,可以使用自定义Dockerfile,修改docker-compose.yml让mysql服务构建自定义镜像:
- 在项目根目录创建
MySQL_Dockerfile,内容调整为:
FROM mysql:latest # 将SQL文件复制到初始化目录 ADD DB_Setup.sql /docker-entrypoint-initdb.d/ # 环境变量建议在docker-compose.yml中配置,更灵活,无需写在这里
- 修改
docker-compose.yml的mysql服务配置,替换image为build:
version: '3' services: php: # 保持原有配置不变 build: context: . dockerfile: Dockerfile volumes: - ./src:/var/www/ ports: - 8080:80 depends_on: - mysql mysql: # 构建自定义镜像 build: context: . dockerfile: MySQL_Dockerfile environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mydatabase MYSQL_USER: user MYSQL_PASSWORD: userpassword volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:
- 同样需要确保首次启动时数据卷为空,执行
docker-compose down -v && docker-compose up -d即可。
内容的提问来源于stack exchange,提问作者JD4867634
相关产品推荐
相关产品推荐

