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/pdocker 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 使用 Redis 时出现连接被拒绝异常