mysql - 启动后在 mySQL 容器中播种数据

标签 mysql docker docker-compose

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

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

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

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

这是我的 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>

我的 app 的 Dockerfile容器有以下 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 容器中运行脚本?

最佳答案

这可以分两步解决:

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

  • 等到开始可以通过添加 来处理依赖 在 docker-compose 文件中:
    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 没有提供 Hook 容器状态的方法。有许多工具和脚本可以解决此问题。

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

    下载 https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh在容器内并删除 入口点字段(您的用例不需要)并使用 命令行 字段:
    CMD ["./wait-for-it.sh", "<db_service_name_as_per_compose_file>:<port>", "--", "/usr/src/app/docker-entrypoint.sh"]
    
  • 现在,这已经完成了。下一部分是执行您的 seed.sql 脚本。
    这很简单,可以通过在您的 中添加以下行来执行/usr/src/app/docker-entrypoint.sh 脚本。

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

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

    关于mysql - 启动后在 mySQL 容器中播种数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60389083/

    相关文章:

    php - 如何将多个复选框答案插入数据库表中?

    php - 不正确的 PHP 时间 - 45 年前的 echo

    docker - 根据用户名转发SSH连接

    docker - docker 安装时的 couchbase 命令

    docker - 如何使用带 docker-compose 的官方 MySQL 镜像为 Docker 容器使用临时卷?

    sql - 使用 EF 迁移历史表中的二进制数据恢复 mysqldump

    php - PDO SQL 查询未按预期工作

    从主机远程安装卷时,Mongodb 不会在 Docker 容器中启动

    docker - 我可以使用环境变量让 Celery worker 连接到不同的 worker 吗?

    postgresql - 连接本地 postgres 数据库时,docker pgAdmin4 连接被拒绝