Docker MySQL - 无法从 Spring Boot 应用程序连接到 MySQL 数据库

Posted

技术标签:

【中文标题】Docker MySQL - 无法从 Spring Boot 应用程序连接到 MySQL 数据库【英文标题】:Docker MySQL - can't connect from Spring Boot app to MySQL database 【发布时间】:2019-10-19 20:14:03 【问题描述】:

我想要做的是,从我的 spring-boot 应用程序连接到 Docker 中的 mysql 数据库。每个都在自己的容器中。

但我一定是做错了什么,因为我做不到。

为简单起见:

应用程序属性:

# URL for the mysql db
spring.datasource.url=jdbc:mysql://workaround-mysql:3308/workaround?serverTimezone=UTC&max_allowed_packet=15728640
# User name in mysql
spring.datasource.username=springuser
# Password for mysql
spring.datasource.password=admin
#Port at which application runs
server.port=8080

用于 MySQL 的 docker-compose:

version: '3'
services:
  workaround-mysql:
    container_name: workaround-mysql
    image: mysql
    environment:
      MYSQL_DATABASE: workaround
      MYSQL_USER: springuser
      MYSQL_PASSWORD: admin
      MYSQL_ROOT_PASSWORD: admin
      MYSQL_ROOT_HOST: '%'
    ports:
      - "3308:3306"
    restart: always

很简单吧?数据库我以docker-compose up开头:

目前看来一切正常。

现在我已经启动了 db,对于应用程序来说,这是它的docker-compose.yml

version: '3'
services:

  workaround:
    restart: always
    # will build ./docker/workaround/Dockerfile
    build: ./docker/workaround
    working_dir: /workaround
    volumes:
      - ./:/workaround
      - ~/.m2:/root/.m2
    expose:
      - "8080"
    command: "mvn clean spring-boot:run"

对于它的Dockerfile,我使用 Linux Alpine 和 Java。

FROM alpine:3.9
....add java...
RUN apk update
RUN apk add dos2unix --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/community/ --allow-untrusted
RUN apk add bash
RUN apk add maven

超级简单。现在让我们启动应用程序:

未知主机,让我们试试IP:

    docker inspect -f 'range .NetworkSettings.Networks.IPAddressend' workaround-mysql

# URL for the mysql db
spring.datasource.url=jdbc:mysql://172.20.0.2:3308/workaround?serverTimezone=UTC&max_allowed_packet=15728640

现在我超时了:

如您所见,我收到错误消息。我的设置有什么问题以及如何解决 这?我有未知的主机异常或拒绝连接或连接超时。

我试过了:

在我的 application.properties 中使用容器的 ip,不起作用 MySQL 和应用程序的不同端口 不同镜像和版本的 MySQL 将所有内容放在一个 docker 中,等待组合 数据库定时器。 最小设置 https://github.com/hellokoding/hellokoding-courses/tree/master/docker-examples/dockercompose-springboot-mysql-nginx 也导致通信链路故障,站点可以访问,但我 怀疑 db 是否连接正确。

注意事项

我在一台计算机上运行这一切我使用端口 3308,因为我有本地 MySQL 数据库位于 3306。

这里是docker ps -a

@Vusal ANSWER 输出:

唯一与答案中的代码不同的是,我确实等待数据库准备好 30 秒

command: /bin/bash -c "sleep 30;mvn clean spring-boot:run;"

【问题讨论】:

容器之间不使用 docker 网络有什么原因吗? @ChristianW。我对他们了解不多,我试图把东西放到同一个网络中。但我仍然没有任何成功。使用 NETWORK : WORKAROUND 对两者都进行了定义。 (也许我没有正确地做某事) 这些东西应该在一个 docker compose 中,否则它不会工作。 @M.Deinum 在我的一次尝试中,我已经这样做了,我目前正在再次这样做以确保我没有搞砸,从下面的答案:) @M.Deinum 仍然出现错误连接被拒绝,即使他们在同一个网络上 【参考方案1】:

到目前为止,您还没有尝试在同一个 Docker 网络上运行两个容器。

首先,忘记 IP 寻址 - 应尽量避免使用它。

其次,使用相同的 Docker 网络启动两个 compose 实例。

第三,不要暴露端口——在桥接网络中,所有端口都可以被运行中的容器访问。

    创建全球网络

     docker network create foo
    

    修改两个 compose 文件,以便它们使用此网络,而不是每个都创建自己的:

     version: '3.5'
     services:
    
     ....
    
     networks:
       default:
         external: true
         name: foo
    

    从撰写文件中删除 expose 指令 - 在一个网络中,所有端口默认公开

    修改连接字符串以使用默认的3306 端口而不是3308

    享受

【讨论】:

会试一试 Bud 如果我删除 3308 的使用,我将与我已经在本地运行的 3306 发生冲突(mysql 数据库),我使用 intellij 进行测试?对吗? version: '3.5' 或更高版本放在 yaml 文件的顶部 “如果我删除 3308 的使用,我将与我已经在本地运行的 3306(mysql 数据库)发生冲突,我使用 intellij 进行测试?对吧?”不,你不会。 3306 将仅存在于网络 foo 内部,并且在外部不可用。据我了解,您从另一个容器而不是主机连接到 db。如果我错了,您还需要从主机连接,则需要公开端口 我已经仔细检查了这个语法,你能确认你没有拼写错误和正确的制表吗?注意 - networks 指令是 GLOBAL,与任何特定服务无关【参考方案2】:

在尝试连接到 Docker 容器之前,您应该在计算机中停止 mysql,然后转到 application.properties 并输入:

spring.datasource.url=jdbc:mysql://localhost:3306/NAME_OF_YOUR_DB_HERE?useSSL=false&allowPublicKeyRetrieval=true

关于 localhost,您应该检查 mysql 容器并选择 IP 地址并使用它。最有可能是 172.17.0.2。如果它不起作用,请使用 localhost。

【讨论】:

【参考方案3】:

试试这个docker-compose.yml

version: '3'
services:
  workaround-mysql:
    container_name: workaround-mysql
    image: mysql
    environment:
      MYSQL_DATABASE: workaround
      MYSQL_USER: springuser
      MYSQL_PASSWORD: admin
      MYSQL_ROOT_PASSWORD: admin
      MYSQL_ROOT_HOST: '%'
    ports:
      - "3308:3306"
    restart: always
  workaround:
    depends_on: 
      - workaround-mysql
    restart: always
    # will build ./docker/workaround/Dockerfile
    build: ./docker/workaround
    working_dir: /workaround
    volumes:
      - ./:/workaround
      - ~/.m2:/root/.m2
    expose:
      - "8080"
    command: "mvn clean spring-boot:run"

并更新您的 application.properties 以使用下一个 JDBC 连接 url:

spring.datasource.url=jdbc:mysql://workaround-mysql:3306/workaround?serverTimezone=UTC&max_allowed_packet=15728640

当两个容器在同一个 docker-compose 文件中时应该可以工作,因为 docker-compose 会为容器创建默认网络,因此它们可以通过名称相互解析。

【讨论】:

我会试试的 好的,所以在我使用了你发给我的代码之后,我的原因是:java.net.ConnectException:连接被拒绝(连接被拒绝)我在尝试这种方法之前已经有过。没有成功,将使用完整输出更新问题 更新了问题并输出到您的答案。 我会测试,因为我仍然使用那个 3308 ,我将它更改为 3306 ,看看它是否从连接被拒绝改变【参考方案4】:

为了让服务通过 docker 与 MySql 连接,它必须在同一个网络中,查看 Docker 网络

但为了更好的解决方案,我建议你为 MySql 和 Spring boot 编写一个 docker compose 文件。原因是这样做很容易链接。不需要任何其他配置。

version: "3"
services:
  mysql-service:
    image: mysql
    ports:
      - "3306:3306"
    environment:
      - MYSQL_DATABASE=db
      - MYSQL_USER=root
      - MYSQL_PASSWORD=pass
      - MYSQL_ROOT_PASSWORD=pass
  spring-service:
    image: springservce:latest
    ports:
      - "8080:8080"
    depends_on:
      - mysql-service

【讨论】:

使用这种风格的撰写文件拒绝连接。 application.properties 中的 jdbc url 应该是这样的 "url=jdbc:mysql://mysql-service:3306/db" (在 doke-compse.yml 中,我已经提到了我的服务名称为“mysql-service”,数据库名称为“db”,这就是为什么在 URL 中使用相同的值)。用户名和密码也是如此 @TomasBisciak,供您参考github.com/aviu95/user_mgt查看代码 是的,我成功了!您的答案与公认的答案非常接近。几乎一样,所以也非常感谢你!

以上是关于Docker MySQL - 无法从 Spring Boot 应用程序连接到 MySQL 数据库的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Spring Boot Docker 容器连接到本地 MySQL 数据库服务器

无法从Spring Boot Docker容器连接到本地MySQL数据库服务器

Docker:无法连接 Spring Boot 和 MYSQL

在 Docker 容器内运行 Spring Boot 应用程序,无法连接 MySQL

Spring Boot 无法连接 MySQL 并在 Docker/Docker compose 中退出

Spring Boot + MySQL + Docker Compose - 无法使 Spring Boot 连接到 MySQL