我的目标是连接两个 docker 容器:一个是一个简单的微服务,一个 Spring Boot 应用程序,另一个是在 Windows 10 本地计算机的 docker 容器中运行的简单 MySQL 数据库。在花了大约 16 个小时尝试连接我的 Spring Boot 后应用程序并尽可能阅读它,并在 StackeOverflow、互联网其他地方和 ChatGTP 中寻找解决方案,我仍然找不到如何连接到另一个容器中的数据库的解决方案。我看到人们问这个问题,当我尝试帮助他们的答案时,它对我不起作用。我一直遇到同样的问题:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
我有 docker-compose.yaml:
version: '3.7'
services:
docker-mysql:
image: mysql:latest
ports:
- "3307:3306"
environment:
MYSQL_DATABASE: wallet_microservice
MYSQL_ROOT_PASSWORD: root
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root
volumes:
- ./src/main/resources/data/schema.sql:/docker-entrypoint-initdb.d/schema.sql
myapp:
build:
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://docker-mysql:3306/wallet_microservice?autoReconnect=true&useSSL=false
depends_on:
- docker-mysql
Dockerfile:
FROM eclipse-temurin:17
WORKDIR /app
COPY build/libs/*.jar app.jar
CMD ["java", "-jar", "app.jar"]
Spring boot应用程序中的application.properties:
spring.datasource.url=jdbc:mysql://docker-mysql:3306/wallet_microservice
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
如果我在与 docker 相同的机器上的 localhost 中运行该应用程序,那么我可以从同一个 Spring boot 应用程序成功连接到此容器中运行的数据库,然后我只需将应用程序的 application.properties 中的数据源行更改为
spring.datasource.url=jdbc:mysql://localhost:3307/wallet_microservice
当我向 ChatGTP 咨询故障排除时,我得到反馈:(所有事情似乎都很好) 网络配置:
我怀疑这是因为您的应用程序在完全初始化之前尝试连接到数据库。
version: '3.7'
services:
docker-mysql:
image: mysql:latest
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: root
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 5s
retries: 5
myapp:
image: mysql:latest
container_name: myapp
depends_on:
docker-mysql:
condition: service_healthy
command: mysql -h docker-mysql -u root -p'root' -e 'SHOW DATABASES;'
您需要使用
depends_on
,但这还不足以检查数据库服务是否已启动。您需要确保实际数据库已初始化并准备好接受连接。
因此,为数据库服务创建一个
healthcheck
,只有当您能够 ping 数据库时,该服务才会通过。然后让您的应用程序等待服务被标记为“健康”。
在
docker-compose.yml
中,我已将您的应用程序替换为一个容器,该容器仅连接到数据库并执行简单的 SQL 查询。这将表明数据库服务已准备就绪。
您可以修改“interval
,
timeoutand
retries”的值,但提供的值是一个合理的起点。