Dockerize Spring Boot mongo

Posted

技术标签:

【中文标题】Dockerize Spring Boot mongo【英文标题】:Dockerize spring boot mongo 【发布时间】:2021-11-17 02:54:54 【问题描述】:

我正在尝试使用 mongodb 后端对 Spring Boot Web 应用程序进行 dockerize。 我运行 mongo 并使用以下命令将其映射到主机:

docker run -p27017:27017 --name my-mongodb-container -d mongo:latest

我已经用 Spring Boot 代码构建了一个 jar,并且能够成功运行它。它插入并打印一些数据。 现在我使用以下 Dockerfile 对这个 jar 进行 dockerize

FROM adoptopenjdk/openjdk11
EXPOSE 8080
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]

我将 docker 容器运行为:

docker run -p 4444:8080 --name mydoctest --link my-mongodb-container doc40

实例出现,尝试连接到 mongo 失败。但是应用程序被加载,因为我有另一个正常运行的 url。但是,它只返回硬编码数据。

我在控制台看到的错误

2021-09-23 17:13:02.725  INFO 1 --- [           main] org.mongodb.driver.cluster               : Cluster created with settings 
hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'
2021-09-23 17:13:02.824  INFO 1 --- [localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread whi
le connecting to server localhost:27017

com.mongodb.MongoSocketOpenException: Exception opening socket
        at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~[mongodb-driver-core-4.2.3.jar!/:na]
        at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:143) ~[mongodb-driver-cor
e-4.2.3.jar!/:na]

任何输入都非常受欢迎

【问题讨论】:

【参考方案1】:

问题始于您的 connectionString 到 mongoDb 和容器的架构

您正在尝试从 java 容器连接到 localhost:27017。在 java 容器中,Mongo 没有运行。而是在另一个容器中运行。您必须更改连接字符串以指向 my-mongodb-container:27017

我会推荐使用 docker networks 而不是 --link 因为它已被弃用 https://docs.docker.com/network/links/

我给你一个简单的例子

docker network create -d brigde app-network
docker run -p27017:27017 --name my-mongodb-container -d mongo:latest
docker network connect app-network my-mongodb-container
docker run -p 4444:8080 --name mydoctest doc40
docker network connect app-network mydoctest

(我没有测试过,如果有错误请告诉我)

取决于您使用的 Mongo 驱动程序,您必须设置 2 个不同的变量来更改您的连接字符串,如 Spring Boot and how to configure connection details to MongoDB? 中所述

spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345 spring.data.mongodb.host=127.0.0.1

所以你可以使用分别创建容器

docker run -p 4444:8080 --name mydoctest -e SPRING_DATA_MONGODB_URI=mongodb://my-mongodb-container:27017 doc40
or
docker run -p 4444:8080 --name mydoctest -e SPRING_DATA_MONGODB_HOST=my-mongodb-container doc40

【讨论】:

嗨 bipe15,我运行了以下命令:docker network create app-network docker run -p27017:27017 --name my-mongodb-container -d mongo:latest docker network connect app-network my-mongodb-container docker run -p 4444:8080 --name mydoctest doc40 docker run -p 4444:8080 --name mydoctest -e SPRING_DATA_MONGODB_URI=mongodb://0.0.0.0:27017 doc40 现在我得到了:Caused by: 'mongoDatabaseFactory' threw exception; nested exception is java.lang.IllegalArgument **Exception: Database name must not be empty!** 对,docker run -p 4444:8080 --name mydoctest -e SPRING_DATA_MONGODB_URI=mongodb://my-mongodb-container:27017/test doc40。请注意,我在连接中添加了 /test 并且还指向 my-mongodb-container,而不是 0.0.0.0 根本不连接...添加主机和数据库后,它会抛出套接字异常。我在 localhost 上运行了 jar,它可以毫无问题地连接到 docker 中的 mongodb。但是我将 jar 复制到 docker,我可以访问 URL,但它无法连接到 mongo。我使用 localhost 来调用 url。在 localhost 或 docker 上运行 jar 的情况下......一切都是一样的。唯一的区别是我托管 spring jar 的 dokcer 容器。【参考方案2】:

终于搞定了。

我所做的唯一更改是在启动时将实例连接到首选 n/w。

docker run -p27017:27017 --name my-mongodb-container --network=app-network -d mongo:latest

docker run -p 4444:8080 --name mydoctest --network=app-network -e SPRING_DATA_MONGODB_URI=mongodb://my-mongodb-container:27017/test doc40

我试图运行容器,然后将其添加到 n/w。

【讨论】:

【参考方案3】:

你的 Docker 主机的 IP 地址是什么?

您的应用尝试使用 localhost 连接到 Mongo。根据您使用的 Docker 安装(考虑到问题,我假设 Docker Toolbox),localhost 将不起作用。您可以尝试使用 Docker 主机的 IP 地址而不是 localhost。大多数情况下,IP 是 192.168.99.100,但也可能是其他的。

你可以通过使用Docker命令行执行docker-machine ip找到地址。

【讨论】:

嗨 KDW,以下是 docker inspect o/p docker inspect <SPRING CONTAINER> "Gateway": "172.17.0.1", "IPAddress": "172.17.0.4", docker inspect <mongo container> "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", 这些是 Docker 用于不同容器的地址,与 docker 主机地址不同。尝试上一个答案中提到的 docker-machine 命令并查看其输出。尝试在连接字符串中使用此地址而不是 localhost。另请查看@bipe15 的评论,因为与我的回答相比,这可能是一种更通用的方法。 其实我在windows上。我正在使用泊坞窗桌面。我找不到 docker-machine 命令。 您确定您的 Mongo 容器正在运行并且在应用程序启动时可以访问吗?您可以使用带有某种 GUI(例如 MongoDB Compass)的 localhost:27017 访问 Mongo 吗?我认为 Docker Desktop 不再为主机使用 192 个地址了。 yes....所以当我从浏览器访问应用程序时,我通过 java -jar myapp.jar 运行 Spring Boot jar,它确实插入并从 mongo 读取值。我也在运行 mongo 并可以访问容器的命令提示符。我可以通过 mongo 控制台连接并查看创建的集合和文档..

以上是关于Dockerize Spring Boot mongo的主要内容,如果未能解决你的问题,请参考以下文章

Dockerize vue js前端和spring boot后端并部署在kubernetes集群上

Spring Boot 和 Redis 容器之间的通信

Spring Boot Redis 使用 Redis 时出现连接被拒绝异常

spring boot 之 spring task(定时任务)

Spring Boot,Cron作业同步

包含Spring Data会破坏Spring Boot应用程序中的自动序列化