3 回答
TA贡献1798条经验 获得超7个赞
我遇到了同样的问题,如果您不想使用任何自定义脚本,可以使用运行状况检查和依赖项轻松解决。使用这些的示例如下:
services:
mysql-db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=vikas1234
- MYSQL_USER=vikas
ports:
- 3306:3306
restart: always
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
timeout: 20s
retries: 10
app:
image: shop-keeper
container_name: shop-keeper-app
build:
context: .
dockerfile: Dockerfile
ports:
- 8080:8080
depends_on:
mysql-db:
condition: service_healthy
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-db:3306/shopkeeper?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: vikas1234
TA贡献1824条经验 获得超8个赞
Docker compose 总是按依赖顺序启动和停止容器,如果没有给出,则在文件中按顺序启动和停止容器。但是 docker-compose 不保证它会等到依赖容器运行。您可以参考此处了解更多详情。所以这里的问题是当你的spring-mysql
容器试图访问数据库时你的数据库还没有准备好。因此,推荐的解决方案是您可以使用wait-for-it.sh或类似的脚本来包装您的spring-mysql
应用程序开始ENTRYPOINT
。
例如,如果您在 Dockerfile 中使用wait-for-it.sh
您的,则在将上述脚本复制到项目根目录后应更改为以下内容:ENTRYPOINT
ENTRYPOINT ["./wait-for-it.sh", "db:3306", "--", "java", "-jar", "app.jar"]
这里要考虑的另外两个重要的事情是:
不要使用它们已被弃用的链接,您应该使用用户定义的网络。如果您没有明确定义任何网络,则 docker-compose 文件中的所有服务都将位于单个用户定义的网络中。所以你只需要从撰写文件中删除链接。
如果仅在用户定义的网络中使用 docker 容器,则无需发布端口。
TA贡献2003条经验 获得超2个赞
你的配置看起来不错,我只推荐:
删除
links: db
.user-defined bridge
它在网络中没有价值删除为 db 公开的端口,除非您想从外部连接
docker-compose
- 所有端口都会在user-defined bridge
网络内部自动公开。
我认为问题在于数据库容器比 web.xml 需要更多的时间来启动。depends_on
只是控制顺序,但不保证您的数据库准备就绪。如果可能,设置几次连接尝试或在您的 Web 容器中放置套接字等待过程。
添加回答
举报