如何在 Docker Compose 中初始化 MySql 数据库
How to init MySql Database in Docker Compose
场景:
我在 Spring 中开发了一个微服务,它使用 mysql 8 数据库。
这个数据库必须被初始化(创建一个数据库,一些表和数据)。
在我的主机上,我使用 data.sql 和 schema.sql 脚本初始化了数据库。
问题是,我必须设置:
spring.datasource.initialization-mode=always
第一次执行。这会按照我想要的方式初始化我的数据库。
为了将来 运行s 我必须评论这个命令。非常难看的解决方案,但我找不到更好的解决方案,而且我现在没有收到对此 question 的回复。
我认为测试它没问题,但我绝对必须改进它。
目前我想 运行 我的服务 docker 通过 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
上,我的微服务比数据库的初始化更快。因此,它会尝试调用导致 en 错误的数据库。
由于 restart on failure
微服务再次出现。
现在它可以工作了,因为数据库的初始化已经完成。
解法:
我搜索了 www,因为它似乎是一个已知问题,可以在 wait-for-it.sh
文件中解决。这必须包含在 Dockerfile 中的 COPY 中。
所以我不是专家,但我正在寻找一个好的解决方案:
- 从 spring 中初始化数据库并让我的服务等待 mysql 就绪
- 或者通过第一个运行上的卷从我的容器中初始化数据库,当然可以解决这个初始化问题。
我不知道这里的最佳实践是什么,我将非常感谢您提供一些帮助来构建它。
仅在第一个 运行 加载您的 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 仅当 DB 的数据目录为空(第一个 运行 数据库服务) 时才会加载此文件夹中的文件。 (即)在你的情况下 ./mysql-data
文件夹应该是空的
对于你的第二个问题:
您可以使用 healthcheck
和 service_healthy
而不是使用 wait-for-it.sh
。这里usermanagement-service
将在mysqldb
在指定的时间间隔内成功执行["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
后启动。有关健康检查和 depends_on 的更多详细信息,请参阅 here。
从 here 获得了 test
命令。
场景: 我在 Spring 中开发了一个微服务,它使用 mysql 8 数据库。 这个数据库必须被初始化(创建一个数据库,一些表和数据)。 在我的主机上,我使用 data.sql 和 schema.sql 脚本初始化了数据库。 问题是,我必须设置:
spring.datasource.initialization-mode=always
第一次执行。这会按照我想要的方式初始化我的数据库。 为了将来 运行s 我必须评论这个命令。非常难看的解决方案,但我找不到更好的解决方案,而且我现在没有收到对此 question 的回复。 我认为测试它没问题,但我绝对必须改进它。 目前我想 运行 我的服务 docker 通过 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
上,我的微服务比数据库的初始化更快。因此,它会尝试调用导致 en 错误的数据库。
由于 restart on failure
微服务再次出现。
现在它可以工作了,因为数据库的初始化已经完成。
解法:
我搜索了 www,因为它似乎是一个已知问题,可以在 wait-for-it.sh
文件中解决。这必须包含在 Dockerfile 中的 COPY 中。
所以我不是专家,但我正在寻找一个好的解决方案:
- 从 spring 中初始化数据库并让我的服务等待 mysql 就绪
- 或者通过第一个运行上的卷从我的容器中初始化数据库,当然可以解决这个初始化问题。
我不知道这里的最佳实践是什么,我将非常感谢您提供一些帮助来构建它。
仅在第一个 运行 加载您的 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 仅当 DB 的数据目录为空(第一个 运行 数据库服务) 时才会加载此文件夹中的文件。 (即)在你的情况下 ./mysql-data
文件夹应该是空的
对于你的第二个问题:
您可以使用 healthcheck
和 service_healthy
而不是使用 wait-for-it.sh
。这里usermanagement-service
将在mysqldb
在指定的时间间隔内成功执行["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
后启动。有关健康检查和 depends_on 的更多详细信息,请参阅 here。
从 here 获得了 test
命令。