mysql - 启动后在 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 容器中运行脚本?
解决方案
这可以分两步解决:
- 您需要等到您的 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"]
现在,这已经完成了。下一部分是执行您的 seed.sql 脚本。这很容易,可以通过在/usr/src/app/docker-entrypoint.sh脚本中添加以下行来执行。
sqlcmd -S -U -P -i 输入查询文件名 -o 输出文件名
在 /usr/src/app/docker-entrypoint.sh 中迁移脚本后放置上述命令
推荐阅读
- javascript - React Redux - 401 - 未经授权 - 请求标头中缺少标头
- vue.js - 组件可以从数据中命名吗?
- python - 有人能告诉我python中随机函数的内部工作吗?
- javascript - 如何通过一次搜索提取多个 JSON 记录
- asp.net - 将循环重定向到 aspx 网站上的旧 URL
- python - 如何从 Python 日期时间对象中删除秒?
- android - 启动新活动时出现“无法找到显式活动类”错误
- delphi - TBitmap32.Assign() 异常行为
- mysql - 如何为 JPA View 实体传递动态限制值?
- php - 使用 php 生成 Laravel 密码