docker spring 引导应用程序无法连接到 docker 化的 mysqldb
docker spring boot application not able to connect to dockerized mysqldb
下面是我的 docker-compose 文件和我的 application.yml 文件。我正在覆盖 docker-compose 文件中的 mysql jdbc url。
为什么我 运行 通过命令行我能够连接到数据库 运行ning 在 docker 实例上。
mysql -uroot -proot -h127.0.0.1 -P3309
当我执行 docker-compose up 时,出现以下错误。 Spring boot docker 实例无法连接到 mysqldb 的 docker 实例。你能帮我理解可能是什么问题吗?
reco-tracker-docker_1 | Caused by: java.lang.RuntimeException: Driver com.mysql.cj.jdbc.Driver claims to not accept jdbcUrl, "jdbc:mysql://mysqldb-docker:3309/reco-tracker-dev"
reco-tracker-docker_1 | at com.zaxxer.hikari.util.DriverDataSource.<init>(DriverDataSource.java:110) ~[HikariCP-4.0.3.jar!/:na]
reco-tracker-docker_1 | at com.zaxxer.hikari.pool.PoolBase.initializeDataSource(PoolBase.java:331) ~[HikariCP-4.0.3.jar!/:na]
reco-tracker-docker_1 | at com.zaxxer.hikari.pool.PoolBase.<init>(PoolBase.java:114) ~[HikariCP-4.0.3.jar!/:na]
docker-compose.yml
version: '3.8'
services:
mysqldb-docker:
image: 'mysql:8.0.27'
restart: 'unless-stopped'
ports:
- "3309:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=reco-tracker-dev
env_file:
- ./.env
volumes:
- mysqldb:/var/lib/mysql
reco-tracker-docker:
image: 'reco-tracker-docker:latest'
ports:
- "8083:8083"
environment:
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root
- SPRING_DATASOURCE_URL="jdbc:mysql://mysqldb-docker:3309/reco-tracker-dev"
depends_on: [mysqldb-docker]
volumes:
mysqldb:
application.yml
server:
port: 8083
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/reco-tracker
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
database-platform: org.hibernate.dialect.MySQL8Dialect
===============================
更新
Post 我在评论区与 [@the-fool] 的讨论,
- 我修改了文件,使 mysql 数据库的主机和容器端口相同,避免了任何混淆。
- 我还更新了 spring 数据源 url 以从环境中传递,即使它覆盖了 application.yml 中已有的数据源。
- 我使用“docker-compose down --rmi all”删除了图像和卷,这样它就删除了容器和卷。 (我之前映射了一个不同的卷,这导致 mysqldb 创建数据库时出现问题)
现在可以使用了!!!
application.yml
server:
port: 8083
spring:
datasource:
username: root
password: root
url: ${SPRING_DATASOURCE_URL}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
database-platform: org.hibernate.dialect.MySQL8Dialect
Dockerfile.yml
FROM openjdk:17
ARG JAR_FILE="*.jar"
COPY target/${JAR_FILE} reco-tracker.jar
EXPOSE 8083
ENTRYPOINT ["java", "-jar","reco-tracker.jar"]
docker-compose.yml
version: '3.8'
services:
mysqldb-docker:
image: 'mysql:8.0.27'
restart: 'unless-stopped'
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=reco-tracker
volumes:
- mysqldb:/var/lib/mysql
reco-tracker-docker:
image: 'reco-tracker-app:v2'
ports:
- "8083:8083"
environment:
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root
- SPRING_DATASOURCE_URL=jdbc:mysql://mysqldb-docker:3306/reco-tracker
depends_on: [mysqldb-docker]
volumes:
mysqldb:
您在这里尝试过 docker“网络”吗?如果没有,则创建一个网络和 运行 同一网络中的容器。
在 yaml 中,类似于:
networks:
-myNet
您的问题是您正试图访问已发布端口上的数据库。您正在使用映射 3309:3306 的 3009。这是行不通的。您不能更改网络内容器的端口。如果要通过 docker 网络连接,则需要使用 3306。 3309 只能从主机系统获得。
至少这部分好像是错的。 (双引号似乎也有问题,我会引用完整的字符串或不引用全部。)
environment:
- SPRING_DATASOURCE_URL="jdbc:mysql://mysqldb-docker:3309/reco-tracker-dev"
在您的 spring 配置中,您使用了正确的端口,但您使用本地主机作为数据库主机,这似乎也是错误的。
spring:
datasource:
url: jdbc:mysql://localhost:3306/reco-tracker
我不太了解 java,所以我无法告诉您它的行为方式。如果以前的 env var 将覆盖它。但就目前而言,这两个设置都有点不正确。
我可以想象你可以通过这样做来修复它。
environment:
# fix the port here
SPRING_DATASOURCE_URL: jdbc:mysql://mysqldb-docker:3306/reco-tracker-dev
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root
spring:
datasource:
# Use the env vars in the spring config
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
还要确保您的数据库命名是一致的。它们在您的 post 中似乎有点不一致。请记住,首次启动 mysql 容器时使用的名称存储在卷中。所以要么使用你当时使用过的名称,要么删除卷让它创建一个新的数据库,这将导致你丢失存储的数据。所以请谨慎选择。
下面是我的 docker-compose 文件和我的 application.yml 文件。我正在覆盖 docker-compose 文件中的 mysql jdbc url。
为什么我 运行 通过命令行我能够连接到数据库 运行ning 在 docker 实例上。
mysql -uroot -proot -h127.0.0.1 -P3309
当我执行 docker-compose up 时,出现以下错误。 Spring boot docker 实例无法连接到 mysqldb 的 docker 实例。你能帮我理解可能是什么问题吗?
reco-tracker-docker_1 | Caused by: java.lang.RuntimeException: Driver com.mysql.cj.jdbc.Driver claims to not accept jdbcUrl, "jdbc:mysql://mysqldb-docker:3309/reco-tracker-dev"
reco-tracker-docker_1 | at com.zaxxer.hikari.util.DriverDataSource.<init>(DriverDataSource.java:110) ~[HikariCP-4.0.3.jar!/:na]
reco-tracker-docker_1 | at com.zaxxer.hikari.pool.PoolBase.initializeDataSource(PoolBase.java:331) ~[HikariCP-4.0.3.jar!/:na]
reco-tracker-docker_1 | at com.zaxxer.hikari.pool.PoolBase.<init>(PoolBase.java:114) ~[HikariCP-4.0.3.jar!/:na]
docker-compose.yml
version: '3.8'
services:
mysqldb-docker:
image: 'mysql:8.0.27'
restart: 'unless-stopped'
ports:
- "3309:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=reco-tracker-dev
env_file:
- ./.env
volumes:
- mysqldb:/var/lib/mysql
reco-tracker-docker:
image: 'reco-tracker-docker:latest'
ports:
- "8083:8083"
environment:
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root
- SPRING_DATASOURCE_URL="jdbc:mysql://mysqldb-docker:3309/reco-tracker-dev"
depends_on: [mysqldb-docker]
volumes:
mysqldb:
application.yml
server:
port: 8083
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/reco-tracker
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
database-platform: org.hibernate.dialect.MySQL8Dialect
=============================== 更新
Post 我在评论区与 [@the-fool] 的讨论,
- 我修改了文件,使 mysql 数据库的主机和容器端口相同,避免了任何混淆。
- 我还更新了 spring 数据源 url 以从环境中传递,即使它覆盖了 application.yml 中已有的数据源。
- 我使用“docker-compose down --rmi all”删除了图像和卷,这样它就删除了容器和卷。 (我之前映射了一个不同的卷,这导致 mysqldb 创建数据库时出现问题)
现在可以使用了!!!
application.yml
server:
port: 8083
spring:
datasource:
username: root
password: root
url: ${SPRING_DATASOURCE_URL}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
database-platform: org.hibernate.dialect.MySQL8Dialect
Dockerfile.yml
FROM openjdk:17
ARG JAR_FILE="*.jar"
COPY target/${JAR_FILE} reco-tracker.jar
EXPOSE 8083
ENTRYPOINT ["java", "-jar","reco-tracker.jar"]
docker-compose.yml
version: '3.8'
services:
mysqldb-docker:
image: 'mysql:8.0.27'
restart: 'unless-stopped'
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=reco-tracker
volumes:
- mysqldb:/var/lib/mysql
reco-tracker-docker:
image: 'reco-tracker-app:v2'
ports:
- "8083:8083"
environment:
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root
- SPRING_DATASOURCE_URL=jdbc:mysql://mysqldb-docker:3306/reco-tracker
depends_on: [mysqldb-docker]
volumes:
mysqldb:
您在这里尝试过 docker“网络”吗?如果没有,则创建一个网络和 运行 同一网络中的容器。
在 yaml 中,类似于:
networks:
-myNet
您的问题是您正试图访问已发布端口上的数据库。您正在使用映射 3309:3306 的 3009。这是行不通的。您不能更改网络内容器的端口。如果要通过 docker 网络连接,则需要使用 3306。 3309 只能从主机系统获得。
至少这部分好像是错的。 (双引号似乎也有问题,我会引用完整的字符串或不引用全部。)
environment:
- SPRING_DATASOURCE_URL="jdbc:mysql://mysqldb-docker:3309/reco-tracker-dev"
在您的 spring 配置中,您使用了正确的端口,但您使用本地主机作为数据库主机,这似乎也是错误的。
spring:
datasource:
url: jdbc:mysql://localhost:3306/reco-tracker
我不太了解 java,所以我无法告诉您它的行为方式。如果以前的 env var 将覆盖它。但就目前而言,这两个设置都有点不正确。
我可以想象你可以通过这样做来修复它。
environment:
# fix the port here
SPRING_DATASOURCE_URL: jdbc:mysql://mysqldb-docker:3306/reco-tracker-dev
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root
spring:
datasource:
# Use the env vars in the spring config
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
还要确保您的数据库命名是一致的。它们在您的 post 中似乎有点不一致。请记住,首次启动 mysql 容器时使用的名称存储在卷中。所以要么使用你当时使用过的名称,要么删除卷让它创建一个新的数据库,这将导致你丢失存储的数据。所以请谨慎选择。