Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpringBoot in Docker not connecting to Mongo in Docker

I have a Spring Boot Application and developed it with a mongo db which was running in brew services.

To get a connection to the db I just had to put the following into application.properties in Spring Boot

spring.data.mongodb.uri=mongodb://localhost:27017/db

changing the application properties to

spring.data.mongodb.uri=mongodb://mongo:27017/db

didtn't change anything, same Error as before.

Now I'm trying to put the SpringBoot Application and the MongoDB into Docker-Containers, but cant get any connection working.

So this is my Dockerfile in the SpringBoot Application:

FROM openjdk:8-jdk-alpine
VOLUME /tmp
EXPOSE 8080
ADD /build/libs/dg-0.0.1-SNAPSHOT.jar dg-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/dg-0.0.1-SNAPSHOT.jar"]

This is my Docker-Compose.yml file:

version: '3'

services:

mongo:
 container_name: docker-mongo
 image: mongo:latest
 ports:
   - "27017:27017"
 volumes:
  - ./data/db:/data/db

spring:
 depends_on:
   - mongo
 image:
   docker-spring-http-alpine
 ports:
   - "8080:8080"
 links:
   - mongo

After executing Docker-Compose with

docker-compose up

I get the following error: (this is the actual error message )

2019-07-08 23:10:19.990  INFO 1 --- [localhost:27017] org.mongodb.driver.cluster: Exception in monitor thread while connecting to server localhost:27017


    com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:67) ~[mongodb-driver-core-3.8.2.jar!/:na]
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:126) ~[mongodb-driver-core-3.8.2.jar!/:na]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117) ~[mongodb-driver-core-3.8.2.jar!/:na]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_212]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_212]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_212]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_212]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_212]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_212]
at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_212]
at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:64) ~[mongodb-driver-core-3.8.2.jar!/:na]
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:62) ~[mongodb-driver-core-3.8.2.jar!/:na]
... 3 common frames omitted

Does someone know whats the problem here? In development environment it works like a charm.

Thanks in advance

Adding the following line to the Dockerfile

"-Dspring.data.mongodb.uri=mongodb://mongo:27017/dg"

into Entrypoint like this solved the connection issue

ENTRYPOINT ["java", "-Dspring.data.mongodb.uri=mongodb://mongo:27017/dg","-Djava.security.egd=file:/dev/./urandom","-jar","/dg-0.0.1-SNAPSHOT.jar"]

I was able to get connection to the db without the mentioned line above in the Entrypoint in the Dockerfile. I guess this is if you like to connect your db over "links"

But now I was able to connect over Network, this is my code:

version: '3.6'

services:

 mongo:
 container_name: docker_mongo
 networks:
   - gateway
 ports:
   - "27017:27017"
 hostname: mongo
 image: mongo:latest
 volumes:
   - ./data/db:/data/db

 spring:
 container_name: docker-spring
 networks:
   - gateway
 ports:
   - "8080:8080"
 hostname: spring
 depends_on:
   - mongo
 image: dg-docker-spring-http-alpine-j
 networks:
gateway:
driver: "bridge"

and the following in application properties

spring.data.mongodb.host=docker_mongo
spring.data.mongodb.port=27017
spring.data.mongodb.database=db

So it looks like the connection is working over Network now. The same code did not work with Version 3.0

To prevent SpringBoot to connect automatically to mongo over localhost it's also necessary to exclude MongoAutoConfiguration!

@SpringBootApplication(exclude={MongoAutoConfiguration.class})

Thank you all for your help

like image 831
midi Avatar asked Jul 08 '19 15:07

midi


People also ask

Can I use MongoDB in Docker?

Can MongoDB Run in a Docker Container? MongoDB can run in a container. The official image available on Docker Hub contains the community edition of MongoDB and is maintained by the Docker team. This image can be used in a development environment.

How do I access Docker in MongoDB?

You can connect to MongoDB on localhost:27017 . Then use the following command to open the MongoDB shell. I have used mymongo as an arbitrary container name, though you can replace mymongo with test-mongo or any other container name of your choosing. The show dbs command will display all your existing databases.

How do I link my local Docker to MongoDB?

For connecting to your local MongoDB instance from a Container you must first allow to accept connections from the Docker bridge gateway. To do so, simply add the respective gateway IP in the MongoDB config file /etc/mongod. conf under bindIp in the network interface section.


2 Answers

EDIT:

I've never done spring-boot development, but the error you are saying is being displayed may very well be unrelated to the mongo issue. However, here is an explanation as to why your mongo-connection is failing:


docker-compose creates a virtual network if one hasn't been specified in the file (like in your case).

All your applications run inside of this network, completely isolated from each other. As such, localhost in your spring-boot container actually refers to itself. Meaning your spring-boot application is expecting the mongo instance to be running inside of its container (which its not, it's in a different container).

This would have been fine when both the database and application was running on your laptop's network. But as mentioned, they are now running in the docker-compose network, in complete isolation.

However, docker-compose is really clever! It creates a DNS for each of your containers which uses the service-name (in your case mongo and spring) specified in your docker-compose file to allow for easy access to the containers inside of the network.

So, you should be able to change spring.data.mongodb.uri=mongodb://localhost:27017/dbto spring.data.mongodb.uri=mongodb://mongo:27017/db and that should allow it to connect.

like image 183
Todai Avatar answered Oct 01 '22 18:10

Todai


Try the following docker-compose.yml. hostname should fix your problem

version: '3'
services:
  mongo:
    container_name: docker-mongo
    image: mongo:latest
    ports:
     - "27017:27017"
    volumes:
     - ./data/db:/data/db
    hostname: mongo

 spring:
   depends_on:
    - mongo
   image:docker-spring-http-alpine
   ports:
    - "8080:8080"
   hostname: spring
   links:
    - mongo
like image 25
Ahmed Lotfy Avatar answered Oct 01 '22 17:10

Ahmed Lotfy