如何在 Docker Compose 中初始化 MySql 数据库
Posted
技术标签:
【中文标题】如何在 Docker Compose 中初始化 MySql 数据库【英文标题】:How to init MySql Database in Docker Compose 【发布时间】:2019-06-26 01:21:47 【问题描述】:场景: 我在 Spring 中开发了一个使用 mysql 8 数据库的微服务。 这个数据库必须被初始化(创建一个数据库,一些表和数据)。 在我的主机上,我使用 data.sql 和 schema.sql 脚本初始化了数据库。 问题是,我必须设置:
spring.datasource.initialization-mode=always
第一次执行。这将以我想要的方式初始化我的数据库。 对于未来的运行,我必须评论这个命令。非常难看的解决方案,但我找不到更好的解决方案,我现在没有对此question 作出任何回应。 我认为测试它是可以的,但我肯定必须改进它。 目前我想通过 docker compose 使用 docker 运行我的服务。
预期: 这是 docker-compose 文件。相当简单。我是 docker 世界的新手,所以我想一步一步来。
version: '3' services:usermanagement-service: build: ./UserManagementService restart: on-failure ports: - "7778:7778" links: - mysqldb depends_on: - mysqldb mysqldb: build: ./CustomMySql volumes: - ./mysql-data:/var/lib/mysql restart: on-failure environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: userdb MYSQL_USER: testuser MYSQL_PASSWORD: testuser expose: - "3600"
我期待的是,我的数据库会使用用户进行初始化,并且在第一次运行时,我的微服务会使用数据初始化数据库。 所以在下次开始撰写之前,我必须评论命令并重建图像。 (我知道,丑)
问题:
因此,除了这个丑陋的解决方案之外,我还遇到了运行时问题。
在docker-compose up
上,我的微服务比数据库的初始化速度更快。所以它试图调用 db 导致错误的结果。
由于restart on failure
,微服务再次出现。
现在它可以工作了,因为 db 的 init 已经完成。
解决方案:
我搜索了 www,这似乎是一个已知问题,可以在 wait-for-it.sh
文件中解决。这必须包含在 Dockerfile 中的 COPY 中。
所以我不是专家,但我正在寻找一个好的解决方案:
我不知道什么是最佳做法
【问题讨论】:
不是您问题的直接解决方案。但是,如果您使用 Flyway 之类的数据库迁移工具,则无需注释/取消注释配置属性。 Flyway会根据当前数据库状态自动运行迁移脚本。 【参考方案1】:仅在第一次运行时加载您的 sql 文件:
您可以使用下面的撰写文件
version: '2.1'
services:
usermanagement-service:
build: ./UserManagementService
restart: on-failure
ports:
- "7778:7778"
depends_on:
mysqldb:
condition: service_healthy
mysqldb:
image: mysql
volumes:
- ./mysql-data:/var/lib/mysql
- ./mysql-init-files:/docker-entrypoint-initdb.d
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: userdb
MYSQL_USER: testuser
MYSQL_PASSWORD: testuser
ports:
- "3600:3306"
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
timeout: 20s
retries: 10
您必须使用Volumes
for more info 将data.sql
和schema.sql
文件放在./docker-entrypoint-initdb.d
目录下。
仅当数据库的数据目录为空(数据库服务的第一次运行)时才会加载此文件夹中的 SQL 文件。 (即)在您的情况下,./mysql-data
文件夹应该是空的
第二个问题:
您可以使用healthcheck
和service_healthy
,而不是使用wait-for-it.sh
。这里usermanagement-service
将在mysqldb
在指定的时间间隔内成功执行["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
后启动。有关 healthcheck 和 depends_on 的更多详细信息,请参阅 here。
从here 得到test
命令。
【讨论】:
感谢您的回答。但是我在使用 depends_on 语法时遇到了问题:services.usermanagement-service.depends_on 包含无效类型,它应该是一个数组:github.com/moby/moby/issues/30404 条件不再支持 您可以将 docker-compose.yml 文件的版本设置为2.1
。喜欢here
但是是否有必要让版本适合我的docker引擎版本,比如here
如果你在集群中部署它是必要的,否则它会起作用。我的 docker 引擎版本是 18.09.1
,我的 compose 文件版本是 2.1
,它就像一个魅力。在上面的link中提到了2.1
版本的compose文件将适用于v1.12.0
之后发布的所有docker引擎版本。以上是关于如何在 Docker Compose 中初始化 MySql 数据库的主要内容,如果未能解决你的问题,请参考以下文章
Docker中的SpringBoot + Postgres:在docker-compose上:无法初始化JPA EntityManagerFactory:无法加载类
如何在 docker-compose.yml 中重建 docker 容器?