在 docker-compose 中使用 MySQL 初始化 Hibernate 时连接被拒绝

Posted

技术标签:

【中文标题】在 docker-compose 中使用 MySQL 初始化 Hibernate 时连接被拒绝【英文标题】:Connection Refused when initializing Hibernate with MySQL in docker-compose 【发布时间】:2020-06-15 07:28:45 【问题描述】:

我有一个用于带有 Hibernate 和 mysql 8 服务器的 SpringBoot 应用程序的 docker-compose。但是每当我的 MySQL 服务器和 SpringBoot 应用程序由 docker-compose 启动时,我得到:

HHH000342: Could not obtain connection to query metadata : Communications link failure
...
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: 
Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
...
Caused by: java.net.ConnectException: Connection refused

这是我的 docker-compose.yaml:

version: '3'
services:
  my-account-microservice-db:
    container_name: my-account-microservice-db
    volumes:
      - /Users/syu/Desktop/my-mysql/storage/my-account-microservice-db:/var/lib/mysql
    image: mysql:8.0.19
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: my-account
    ports:
      - "3307:3306"
    networks:
      - my-network

  my-account-microservice:
    container_name: my-account-microservice
    image: my-account-microservice
    build:
      context: ./account-microservice
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://my-account-microservice-db:3307/my-account
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: password
      SPRING_DATASOURCE_DRIVER-CLASS-NAME: com.mysql.cj.jdbc.Driver
      # SPRING.DATASOURCE.URL: jdbc:mysql://my-account-microservice-db:3307/my-account
      # SPRING.DATASOURCE.USERNAME: root
      # SPRING.DATASOURCE.PASSWORD: password
      # SPRING.DATASOURCE.DRIVER-CLASS-NAME: com.mysql.cj.jdbc.Driver
      # DATABASE_HOST: my-account-microservice-db
      # DATABASE_USER: root
      # DATABASE_PASSWORD: password
      # DATABASE_PORT: 3307
    depends_on:
      - my-account-microservice-db
    ports:
      - "8090:8090"
    networks:
      - my-network
#    links:
#      - my-account-microservice-db:database

networks:
  my-network:

还有我的 application.properties:

spring.application.name=account-microservice

server.port=8090

# ==============================================================
# = Data Source
# ==============================================================
# ******** Will probably put this on a central config server? would that work?
spring.datasource.url = jdbc:mysql://localhost:3307/my-account
spring.datasource.username = root
spring.datasource.password = password
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver

# ==============================================================
# = Show or not log for each sql query
# ==============================================================
spring.jpa.show-sql = true

# ==============================================================
# = Keep the connection alive if idle for a long time (needed in production)
# ==============================================================
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1

# ==============================================================
# = Hibernate ddl auto (create, create-drop, update)
# = The SQL dialect makes Hibernate generate better SQL for the chosen database
# ==============================================================
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl = true
spring.jpa.hibernate.ddl-auto = update

我已经验证了以下几点:

    MySQL 在 SpringBoot 应用程序启动之前启动 尝试使用 -links,但没有成功 没有任何东西在使用端口 3307 我可以使用/bin/mysql -h0.0.0.0 -uroot -ppassword 连接到 localhost:3307 非常好 让他们在同一个网络上 重启 Docker 通过在服务器上运行 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' 确保 root 用户具有权限 使用单个 DockerFile 运行 具有正确的 mysql 连接器和 Hibernate 依赖项

但是我上面尝试过的所有事情都没有奏效。 *奇怪的是,我的 SpringBoot 应用程序能够连接到 mysql 数据库,如果我不使用 Docker 自己启动应用程序(仅使用 IntelliJ 的 SpringBoot 配置)

我不知道我做错了什么。请帮忙^

【问题讨论】:

【参考方案1】:

你在主机端口3307上暴露了数据库容器的3306端口。但是,容器端口仍然是3306。所以当你连接到数据库容器时,你应该连接到端口3306

如果您想从运行它的主机连接到您的数据库容器,请使用 localhost:3307。但是,这不适用于在您的主机上运行的容器。对于这些,请使用 container:3306。

【讨论】:

哦,天哪,我不敢相信这是原因,应该考虑清楚...它有效,谢谢您的帮助!

以上是关于在 docker-compose 中使用 MySQL 初始化 Hibernate 时连接被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

在 docker-compose 的 .env 文件中使用多行值

如何使用 pycharm 调试在 docker-compose 中运行的进程

是否可以在 DockerComposeContainer 的 docker-compose 文件中使用本地 Docker 映像?

使用 docker-compose 在 Docker 中运行 laravel/lumen

在 GitLab CI 管道中使用 docker-compose

在 gitlab ci 中使用 ssh docker-compose 到远程主机失败