Docker编写的MySql初始化脚本未执行

时间:2018-11-21 07:29:16

标签: mysql spring-boot docker docker-compose

我在使用mysql容器运行初始化脚本时遇到问题。

我有两个文件 create.sql insert.sql ,它们用于初始化数据库。

我使用命令 docker-compose.yml 创建图像,该命令成功运行并创建图像。

我面临两个问题。

  1. 当我运行 docker-compose up 命令时,将创建并成功启动mysql容器。但是,两个初始化脚本( create.sql insert.sql )不在数据库上运行。

  2. 我明确使用 docker run 命令运行创建的mysql容器。在这种情况下,初始化脚本会成功运行

我正在使用 Docker 版本 18.09.0 docker-compose 版本 1.23.1 和ubuntu < strong> 16.04 LTS

我是docker的新手,似乎无法解决问题。


以下是我用来创建图像的文件。

docker-compose.yml 文件。

version: '3'

services:
  demo-mysql:
    image: demo-mysql
    build: ./demo-mysql
    volumes:
      - /mnt/data/mysql-data:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=demo
      - MYSQL_PASSWORD=root

  demo-api:
    image: demo-api-1.0
    build: ./api
    depends_on:
      - demo-mysql
    ports:
      - 8080:8080
    environment:
      - DATABASE_HOST=demo-mysql
      - DATABASE_USER=root
      - DATABASE_PASSWORD=root
      - DATABASE_NAME=demo
      - DATABASE_PORT=3306

  demo1-app:
    image: demo1-app-1.0
    build: ./demo1
    depends_on:
      - demo-mysql
    ports:
      - 8090:8090
    environment:
      - DATABASE_HOST=demo-mysql
      - DATABASE_USER=root
      - DATABASE_PASSWORD=root
      - DATABASE_NAME=demo
      - DATABASE_PORT=3306

以下是spring boot项目的 Dockerfile

FROM java:8

VOLUME /tmp

ARG DATA_PATH=/src/main/resources
ARG APP_PORT=8080

EXPOSE ${APP_PORT}

ADD /build/libs/demo-api.jar demo-api.jar

ENTRYPOINT ["java","-jar","demo-api.jar"]

以下是我用来创建mysql映像的 Dockerfile

FROM mysql:5.7

ENV MYSQL_DATABASE=demo \
    MYSQL_USER=root \
    MYSQL_ROOT_PASSWORD=root

ADD ./1.0/create.sql /docker-entrypoint-initdb.d
ADD ./1.0/insert.sql /docker-entrypoint-initdb.d

EXPOSE 3306

1 个答案:

答案 0 :(得分:0)

摘自文档(https://hub.docker.com/_/mysql/

  

初始化一个新实例

     

第一次启动容器时 ,一个新数据库   指定的名称将创建并使用提供的名称进行初始化   配置变量。此外,它将执行带有   在.sh,.sql和.sql.gz中找到的扩展名   /docker-entrypoint-initdb.d。

我怀疑是因为体积持续存在

volumes:
      - /mnt/data/mysql-data:/var/lib/mysql

当docker启动mysql镜像时,已经有一个DB。因此,图像不是“新鲜”的,脚本也不会运行。

更新: 我们可以在https://github.com/docker-library/mysql/blob/696fc899126ae00771b5d87bdadae836e704ae7d/5.7/docker-entrypoint.sh

处查看docker-entrypoint.sh的源代码来确认该嫌疑犯。
if [ ! -d "$DATADIR/mysql" ]; then
...
...
        ls /docker-entrypoint-initdb.d/ > /dev/null
        for f in /docker-entrypoint-initdb.d/*; do
            process_init_file "$f" "${mysql[@]}"
        done

仅当"$DATADIR/mysql"不存在时脚本才运行。

顺便说一句,我个人认为一个更好的设计是让“应用程序”在启动时创建数据库模式,预加载所需的应用程序数据,管理模式迁移等,但这是另一个主题:)