Docker compose 等待数据库服务初始化
Posted
技术标签:
【中文标题】Docker compose 等待数据库服务初始化【英文标题】:Docker compose wait for database service initialisation 【发布时间】:2019-04-23 17:46:12 【问题描述】:我有一个 Spring Boot 项目,我想使用 docker 对其进行容器化。 我有几个连接到同一个 mysql 服务器的 Spring Boot 应用程序。
我的 spring 应用程序需要完全设置数据库(即要创建所有表并在某些表中插入一些数据)才能启动。
我正在使用 Docker 版本 18.09.0 和 docker-compose 版本 1.23.1 和 ubuntu 16.04 LTS
我有两个文件 create.sql
和 insert.sql
,我用它们来初始化应用程序使用的数据库。
我使用命令 docker-compose.yml
创建图像,它成功运行并创建图像。
我有以下问题。
我假设在使用 docker-compose 时,容器会在其所有依赖容器启动后立即启动。在我的 API 容器启动之前,有没有办法等待 mysql 服务器启动并准备好接受连接?
如果我选择为应用程序和 mysql 分别创建容器,而不使用 docker-compose,如何确保我的应用程序连接到 mysql 容器?
还有其他工具可以帮助我实现这一目标吗?
注意:
我曾尝试使用 docker inspect <container_id>
查找 mysql 容器的 IpAddress 并使用它进行连接,但效果不佳。
以下是我用来创建图像的文件。
docker-compose.yml
文件。
version: '3'
services:
demo-mysql:
image: demo-mysql
build: ./demo-mysql
volumes:
- /mnt/data/mysql-data:/var/lib/mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=demo
- MYSQL_PASSWORD=root
demo-api:
image: demo-api-1.0
build: ./api
depends_on:
- demo-mysql
ports:
- 8080:8080
environment:
- DATABASE_HOST=demo-mysql
- DATABASE_USER=root
- DATABASE_PASSWORD=root
- DATABASE_NAME=demo
- DATABASE_PORT=3306
demo1-app:
image: demo1-app-1.0
build: ./demo1
depends_on:
- demo-mysql
ports:
- 8090:8090
environment:
- DATABASE_HOST=demo-mysql
- DATABASE_USER=root
- DATABASE_PASSWORD=root
- DATABASE_NAME=demo
- DATABASE_PORT=3306
以下是spring boot项目的Dockerfile
FROM java:8
VOLUME /tmp
ARG DATA_PATH=/src/main/resources
ARG APP_PORT=8080
EXPOSE $APP_PORT
ADD /build/libs/demo-api.jar demo-api.jar
ENTRYPOINT ["java","-jar","demo-api.jar"]
以下是我用来创建mysql镜像的Dockerfile
FROM mysql:5.7
ENV MYSQL_DATABASE=demo \
MYSQL_USER=root \
MYSQL_ROOT_PASSWORD=root
ADD ./1.0/create.sql /docker-entrypoint-initdb.d
ADD ./1.0/insert.sql /docker-entrypoint-initdb.d
EXPOSE 3306
【问题讨论】:
【参考方案1】:使用 docker-compose (https://docs.docker.com/compose/compose-file/#healthcheck) 的 healthcheck
功能。
像这样的:
services:
demo-mysql:
image: demo-mysql
build: ./demo-mysql
volumes:
- /mnt/data/mysql-data:/var/lib/mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=demo
- MYSQL_PASSWORD=root
healthcheck:
test: ["CMD-SHELL", 'mysqladmin ping']
interval: 10s
timeout: 2s
retries: 10
在 demo-mysql 容器健康之前,依赖的容器不会启动
【讨论】:
@greenPadawan:你是对的,需要使用“mysqladmin ping”进行健康检查。 健康检查不再有帮助,在 docker 3 中已经删除了 depends_on 的条件,所以即使你添加你的 spring boot 应用程序依赖于数据库,它也会等待它运行,而不是准备好了。 @GeorgeMarin:对,目前支持的方式:docs.docker.com/compose/startup-order 请更新答案,因为这不再有效。请参阅上面的评论。 您好,我建议您在运行状况检查脚本中使用/usr/bin/mysql --user=root --password=root --execute "SHOW DATABASE;"
而不是mysqladmin ping
。这等待真正的初始化。以上是关于Docker compose 等待数据库服务初始化的主要内容,如果未能解决你的问题,请参考以下文章
如何在 docker-compose.yml 中开始测试之前等待数据库迁移完成
在创建其他服务之前,等待在docker compose中准备好mysql服务
docker-compose 等待启动,直到挂载主机文件系统
使用docker-compose时,Healthcheck根本不起作用(我的服务在启动前不等待Kafka启动)