简体   繁体   English

如何在 Spring Boot Docker 中连接到 MongoDB Atlas?

[英]How can I connect to MongoDB Atlas inside Spring Boot Docker?

I would like to deploy a Spring Boot application to Docker, but it is unable to connect to my database set up in MongoDB Atlas.我想将 Spring Boot 应用程序部署到 Docker,但它无法连接到我在 MongoDB Atlas 中设置的数据库。 The app starts up fine, but connection to the repository is refused when I attempt to run docker-compose up .该应用程序启动正常,但当我尝试运行docker-compose up时,与存储库的连接被拒绝。

The exception:例外:

app-server_1  | 2021-07-27 18:56:54.599  INFO 1 --- [           main] org.mongodb.driver.cluster               : Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
app-server_1  | 2021-07-27 18:56:54.817  INFO 1 --- [localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
app-server_1  |
app-server_1  | com.mongodb.MongoSocketOpenException: Exception opening socket
app-server_1  |         at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~[mongodb-driver-core-4.1.2.jar!/:na]
app-server_1  |         at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:143) ~[mongodb-driver-core-4.1.2.jar!/:na]
app-server_1  |         at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:188) ~[mongodb-driver-core-4.1.2.jar!/:na]
app-server_1  |         at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:144) ~[mongodb-driver-core-4.1.2.jar!/:na]
app-server_1  |         at java.lang.Thread.run(Thread.java:748) [na:1.8.0_292]
app-server_1  | Caused by: java.net.ConnectException: Connection refused (Connection refused)
app-server_1  |         at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_292]
app-server_1  |         at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_292]
app-server_1  |         at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_292]
app-server_1  |         at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_292]
app-server_1  |         at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_292]
app-server_1  |         at java.net.Socket.connect(Socket.java:607) ~[na:1.8.0_292]
app-server_1  |         at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:78) ~[mongodb-driver-core-4.1.2.jar!/:na]
app-server_1  |         at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:79) ~[mongodb-driver-core-4.1.2.jar!/:na]
app-server_1  |         at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:65) ~[mongodb-driver-core-4.1.2.jar!/:na]
app-server_1  |         ... 4 common frames omitted

application.properties:应用程序属性:

spring.datasource.url = mongodb+srv://admin:myPassword@cluster0.gf9zs.mongodb.net/my-app?retryWrites=true&w=majority
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.database=my-app

docker-compose.yml - I think that the mongo service specified here is like running a separate database rather than connecting remotely like in application.properties. docker-compose.yml - 我认为这里指定的mongo服务就像运行一个单独的数据库,而不是像 application.properties 中的远程连接。 I would prefer to connect to Atlas since it is inexpensive.我更愿意连接到 Atlas,因为它很便宜。 For now, I left mongo as an orphan service.现在,我离开mongo作为孤儿服务。

version: '3.7'
services:
  mongo:
    container_name: mongodb
    image: mongo
    volumes:
      - ./database:/data
    ports:
      - "27017:27017"

  # App backend service
  app-server:
    build:
      context: my-app-spring
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    restart: always
    depends_on: 
      - mongo # This service depends on MongoDB. Start that first.
    

Dockerfile文件

FROM scratch
FROM openjdk:8
RUN mvn install
EXPOSE 8080
ADD target/my-app.jar my-app.jar 
ENTRYPOINT ["java","-jar","/my-app.jar"]

What I have tried我试过的

  • Setting IP access to everywhere from the Atlas dashboard从 Atlas 仪表板设置对任何地方的 IP 访问
  • Adding the username and password to separate Spring Boot properties添加用户名和密码以分离 Spring Boot 属性
  • Running the app outside of Docker.在 Docker 之外运行应用程序。 This works, but only if I have MongoDB Service running.这有效,但前提是我运行了 MongoDB 服务。 Maybe Docker needs its own MongoDB Service inside the container in order to connect to the database, which is outside the container.也许 Docker 需要在容器内有自己的 MongoDB 服务才能连接到容器外的数据库。
  • Following this guide: https://developer.mongodb.com/how-to/use-atlas-on-heroku/ .遵循本指南: https : //developer.mongodb.com/how-to/use-atlas-on-heroku/ The goal is ultimately to deploy the Docker container to Heroku.最终目标是将 Docker 容器部署到 Heroku。
  • Looking at other SO questions.查看其他 SO 问题。 Usually, the OP had mistakenly written "localhost" somewhere.通常,OP 在某处错误地写了“localhost”。
  • Checking my Firewall access检查我的防火墙访问

Question: How can I resolve this exception?问题:如何解决此异常? What are some probable causes of it?它的一些可能原因是什么?

I figured it out, but I'm not using Atlas just yet.我想通了,但我还没有使用 Atlas。 The problem was that I needed the mymongodb container name to match the spring.data.mongodb.host property in application.properties.问题是我需要mymongodb容器名称来匹配spring.data.mongodb.host中的spring.data.mongodb.host属性。 When docker-compose up didn't work, I built the images separately then tested them.docker-compose up不起作用时,我单独构建图像然后测试它们。 These are the troubleshooting commands I ran:这些是我运行的故障排除命令:

docker pull mongo:latest
docker run -d -p 27017:27017 --name mymongodb mongo:latest
docker build -t springboot-mongodb:1.0 . #you need to run mvn clean install and be in the directory of the Dockerfile in order for this to work
docker run -p 8080:8080 --name springboot-mongodb --link mymongodb:mongo -d springboot-mongodb:1.0

These commands prepare MongoDB and Spring Boot images then run them as linked containers.这些命令准备 MongoDB 和 Spring Boot 映像,然后将它们作为链接容器运行。 If these commands work, then you should be able to reach your API with Postman then proceed to write a docker-compose.yml file such as the one below.如果这些命令有效,那么您应该能够使用 Postman 访问您的 API,然后继续编写一个docker-compose.yml文件,如下所示。

Here are the working files:以下是工作文件:

application.properties:应用程序属性:

spring.data.mongodb.host=mymongodb
spring.data.mongodb.port=27017

docker-compose.yml: docker-compose.yml:

version: "3"
services:
 mymongodb:
   image: mongo:latest
   container_name: "mymongodb"
   ports:
     - 27017:27017
 springboot-mongodb:
   build:
     context: my-app-spring
     dockerfile: Dockerfile
   container_name: springboot-mongodb
   ports:
     - 8080:8080
   links:
     - mymongodb 

Dockerfile: Dockerfile:

FROM adoptopenjdk/openjdk11:alpine-jre
ADD target/my-app.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM