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] 的讨论,

  1. 我修改了文件,使 mysql 数据库的主机和容器端口相同,避免了任何混淆。
  2. 我还更新了 spring 数据源 url 以从环境中传递,即使它覆盖了 application.yml 中已有的数据源。
  3. 我使用“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 容器时使用的名称存储在卷中。所以要么使用你当时使用过的名称,要么删除卷让它创建一个新的数据库,这将导致你丢失存储的数据。所以请谨慎选择。