首页 > 解决方案 > 启动后在 mySQL 容器中播种数据

问题描述

我有一个要求,我需要等待一些命令才能为数据库的数据播种:

我有一些在数据库中创建架构的迁移脚本(此命令从我的应用程序容器运行)。执行此操作后,我想将数据播种到数据库中。

正如我所读到的,docker-entrypoint-initdb脚本是在容器初始化时执行的。如果我将seed.sql脚本挂载到它,则数据会在 Migrate 脚本之前播种。(迁移脚本实际上会删除所有表并从头开始创建它们)。因此,种子数据丢失。

我怎样才能做到这一点?(我无法更改迁移脚本)

这是我的 docker-compose.yml 文件

version: '3'
services:
  app:
    build: .
    # mount the current directory (on the host) to /usr/src/app on the container, any changes in either would be reflected in both the host and the container
    volumes:
      - .:/usr/src/app
    # expose application on localhost:36081
    ports:
      - "36081:36081"
    # application restarts if stops for any reason - required for the container to restart when the application fails to start due to the database containers not being ready
    restart: always
    environment:
      MIGRATE: Y
      <some env variables here>
  config-dev:
    image: mysql/mysql-server:5.7
    environment: 
      MYSQL_DATABASE: config_dev
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' 
    volumes:
      # to persist data
      - config-dev-volume:/var/lib/mysql
    restart: always
    # to connect locally from SequelPro
    ports:
      - "1200:3306"
  <other database containers>

我的容器 Dockerfileapp具有以下内容ENTRYPOINT

# start the application
ENTRYPOINT /usr/src/app/docker-entrypoint.sh

这是 docker-entrypoint.sh 文件

#!/bin/bash

if [ "$MIGRATE" = "Y" ];
then
    <command to start migration scripts>
    echo "------------starting application--------------"
    <command to start application>
else
    echo "------------starting application--------------"
    <command to start application>
fi

编辑:有没有办法可以从 app 容器中的 docker-entrypoint.sh 文件在 config-db 容器中运行脚本?

标签: mysqldockerdocker-compose

解决方案


这可以分两步解决:

  1. 您需要等到您的 db 容器启动并准备就绪。

等到开始可以通过在 docker-compose 文件中添加depends_on来处理:

version: '3'
services:
  app:
    build: .
    # mount the current directory (on the host) to /usr/src/app on the container, any changes in either would be reflected in both the host and the container
    depends_on:
      - config-dev
      - <other containers (if any)>
    volumes:
      - .:/usr/src/app
    # expose application on localhost:36081
    ports:
      - "36081:36081"
    # application restarts if stops for any reason - required for the container to restart when the application fails to start due to the database containers not being ready
    restart: always
    environment:
      MIGRATE: Y
      <some env variables here>
  config-dev:
    image: mysql/mysql-server:5.7
    environment: 
      MYSQL_DATABASE: config_dev
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' 
    volumes:
      # to persist data
      - config-dev-volume:/var/lib/mysql
    restart: always
    # to connect locally from SequelPro
    ports:
      - "1200:3306"
  <other database containers>

等到 db 准备好是另一种情况,因为有时 db 进程开始侦听 tcp 端口需要时间。不幸的是,Docker 没有提供挂钩容器状态的方法。有许多工具和脚本可以解决此问题。

您可以通过它来实施解决方法。 https://docs.docker.com/compose/startup-order/ TL;DR

在容器内下载https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh并删除ENTRYPOINT字段(您的用例不需要)并改用CMD字段:

CMD ["./wait-for-it.sh", "<db_service_name_as_per_compose_file>:<port>", "--", "/usr/src/app/docker-entrypoint.sh"]
  1. 现在,这已经完成了。下一部分是执行您的 seed.sql 脚本。这很容易,可以通过在/usr/src/app/docker-entrypoint.sh脚本中添加以下行来执行。

    sqlcmd -S -U -P -i 输入查询文件名 -o 输出文件名

在 /usr/src/app/docker-entrypoint.sh 中迁移脚本后放置上述命令


推荐阅读