Time out when connect docker image to a mongodb - java

I met a time out exception when I trying connect a docker image to a local mongodb
The error is
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'getBuilder' defined in io.mongock.runner.springboot.config.MongockContext: Unsatisfied dependency expressed through method 'getBuilder' parameter 0: Error creating bean with name 'connectionDriver' defined in class path resource [io/mongock/driver/mongodb/springdata/v4/config/SpringDataMongoV4Context.class]: Failed to instantiate [io.mongock.driver.api.driver.ConnectionDriver]: Factory method 'connectionDriver' threw exception with message: Timed out after 30000 ms while waiting to connect. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}]
Here is my docker file and entrypoint for my image
dockerfile
FROM openjdk:17
COPY /build/libs/demo-0.0.2-SNAPSHOT.jar Demo-0.0.2.jar
COPY entrypoint.sh entrypoint.sh
RUN chmod +x entrypoint.sh
EXPOSE 3000
ENTRYPOINT ./entrypoint.sh
entrypoint.sh
java -jar -Dspring.data.mongodb.uri="$MONGODB_URI" Demo-0.0.2.jar
Here is the docker compose file for mongodb
version: '3.8'
services:
mongodb:
image: mongo:latest
container_name: dev_mongo
restart: always
environment:
- MONGO_INITDB_DATABASE=admin
- MONGO_INITDB_ROOT_USERNAME=dev_mongo_username
- MONGO_INITDB_ROOT_PASSWORD=dev_mongo_pwd
ports:
- "27018:27017"
volumes:
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
- type: volume
source: mongodb_data
target: /data/db
networks:
- mongo_network
networks:
mongo_network:
driver: bridge
volumes:
mongodb_data:
And here is the command line I used to run the docker image
docker run --env MONGODB_URI="mongodb://local_mongo_username:local_mongo_pwd#localhost:27017/?authSource=admin&tls=false" --name test_app1 -d -p 3000:3000 demo:latest
How can I solve this problem and connect to mongodb successfully ?

Related

Getting "Exception opening socket" on Mongodb connection from Spring App (docker-compose)

Even though I'm giving in the application properties,
spring.data.mongodb.host=api-database4
as the hostname which is the container name and hostname of the MongoDB on the docker-compose file, Spring app still can't connect to the MongoDB instance. I can however connect from MongoDB Compass to localhost:27030 but not to mongodb://api-database4:27030/messagingServiceDb.
My docker-compose file;
version: '3'
services:
messaging-api6:
container_name: 'messaging-api6'
build: ./messaging-api
restart: always
ports:
- 8085:8080
depends_on:
- api-database4
networks:
- shared-net
api-database4:
image: mongo
container_name: api-database4
hostname: api-database4
restart: always
ports:
- 27030:27017
networks:
- shared-net
command: mongod --bind_ip_all
networks:
shared-net:
driver: bridge
and my Docker file for the Spring app is;
FROM openjdk:12-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
and my application.properties are;
#Local MongoDB config
spring.data.mongodb.database=messagingServiceDb
spring.data.mongodb.port=27030
spring.data.mongodb.host=api-database4
Entire code can be seen here.
How can I make my spring app on a docker container create a connection to the MongoDB instance which is on another docker container?
I have tried the solutions on similar questions and replicated them, it still gives the same error.
Edit and Solution:
I solved the issue by commenting out configuration below,
#Local MongoDB config
#spring.data.mongodb.database=messagingServiceDb
spring.data.mongodb.host=api-database4
spring.data.mongodb.port=27030
The remaining question is, why? That was the correct port that I'm trying to connect. Could it be related to the configuration order?
ports directive in docker-compose publishes container ports to the host machine. The containers communicate with each other on exposed ports. You can test whether a container can reach another with netcat.
docker exec -it messaging-api6 bash
> apt-get install netcat
> nc -z -v api-database4 27030
> nc -z -v api-database4 27017

How to Dockerize Jmeter (Distributed testing with Docker and Jmeter)

I am using the jmeter 5.2 and the plugin 1.4.0. I am trying to dockerize the my automations in jmeter. But i take an error like following;
Error in rconfigure() method java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: org.apache.jmeter.assertions.JSONPathAssertion (no security manager: RMI class loader disabled)
My Docker-compose file;
version: '3.3'
services:
master:
build: ..
command: master
tty: true
ports:
- "60000"
volumes:
- "./test/:/jmeter/sample/"
networks:
- jmeter-network
server:
image: pedrocesarti/jmeter-docker:latest
command: server
tty: true
ports:
- "50000"
- "1099"
networks:
- jmeter-network
depends_on:
- master
networks:
jmeter-network:
I've tried a lot of solutions but i cannot resolve this problem. Could you help me please? Thanks.
Looking into Dockerfile for pedrocesarti/jmeter-docker
ENV JMETER_VERSION ${JMETER_VERSION:-3.3}
and your test seems to be using JSON Assertion which is available since JMeter 4.0
So you need to replace the JMETER_VERSION variable with version 4.0 or higher and your script should start working as expected.

facing connection refused error while trying to run test cases from one container which is hitting the zalenium container

When running my selenium testcases on Zalenium grid locally and it runs fine. I have created image of my project using the docker file below. i have written the docker compose file to start the zalenium grid . But when trying to run image of my project to create container and run test cases inside my container it is giving connection refused error.
Dockerfile of my project to create image is below
FROM openjdk:11.0.1-debian
VOLUME /tmp
ADD web_runnable.jar app.jar
ADD cacerts cacerts
ADD config.properties config
EXPOSE 8000
ENV USERNAME xyz
ENV PASSWORD xyz
ENV GRID true
ENTRYPOINT sh -c 'java -jar -Dconfig=config -DuserName=$USERNAME -Dpassword=$PASSWORD -Dgrid=$GRID -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStore=cacerts /app.jar com.tsys.driverscript.DriverScript.class'
Docker compose file to start zalenium is below
version: '3.5'
services:
zalenium:
image: dosel/zalenium
container_name: zalenium_container
networks:
- main
restart: always
ports:
- "4444:4444"
command: ["start", "--desiredContainers", "1", "--maxDockerSeleniumContainers", "1","--sauceLabsEnabled","false","--screenWidth", "1280", "--screenHeight", "720" , --timeZone , "Asia/Kolkata", "--seleniumImageName","elgalu/selenium:latest"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /Users/nikitatorane/videos:/home/seluser/videos
privileged: true
selenium:
image: elgalu/selenium:latest
container_name: selenium_container
networks:
- main
restart: always
networks:
main:
name: main
I have setup my huburl as below :
NODE = "http://zalenium:4444/wd/hub";
When I'm trying to run image using with setting the same network on which zalenium is running then also i am getting connection refused error being all containers in same network.
Command to build image of my project is below :
docker build -t xyz:1.2
command to run my project image is below :
docker run -it --net=main xyz:1.2
error while running image is below :*
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:591)
at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:74)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141)
... 52 more
I even tried to link two containers and then also getting same error as above. Can anyone go through this and let me know where I am going wrong ?

Spring Boot + docker-compose + MySQL: Connection refused

I'm trying to set up a Spring Boot application that depends on a MySQL database called teste in docker-compose. After issuing docker-compose up, I'm getting:
Caused by: java.net.ConnectException: Connection refused (Connection refused)
I'm running on Linux Mint, my docker-compose version is 1.23.2, my Docker version is 18.09.0.
application.properties
# JPA PROPS
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.datasource.url=jdbc:mysql://db:3306/teste?useSSL=false&serverTimezone=UTC
spring.datasource.username=rafael
spring.datasource.password=password
spring.database.driverClassName =com.mysql.cj.jdbc.Driver
docker-compose.yml
version: '3.5'
services:
db:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=teste
- MYSQL_USER=rafael
- MYSQL_PASSWORD=password
ports:
- 3306:3306
web:
image: spring-mysql
depends_on:
- db
links:
- db
ports:
- 8080:8080
environment:
- DATABASE_HOST=db
- DATABASE_USER=rafael
- DATABASE_NAME=teste
- DATABASE_PORT=3306
and the Dockerfile
FROM openjdk:8
ADD target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Docker compose always starts and stops containers in dependency order, or sequential order in the file if not given. But docker-compose does not guarantee that it will wait till the dependency container is running. You can refer here for further details. So the problem here is that your database is not ready when your spring-mysql container tries to access the database. So, the recommended solution is you could use wait-for-it.sh or similar script to wrap your spring-mysql app starting ENTRYPOINT.
As example if you use wait-for-it.sh your ENTRYPOINT in your Dockerfile should change to following after copying above script to your project root:
ENTRYPOINT ["./wait-for-it.sh", "db:3306", "--", "java", "-jar", "app.jar"]
And two other important thing to consider here is:
Do not use links they are deprecated you should use user-defined network instead. All services in docker-compose file will be in single user-defined network if you don't explicitly define any network. So you just have to remove the links from compose file.
You don't need to publish the port for docker container if you only use it inside the user-defined network.
I was facing the same issue and in case you do not want to use any custom scripts, this can easily be resolved using health checks along with depends on. A sample using these is as follows:
services:
mysql-db:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=vikas1234
- MYSQL_USER=vikas
ports:
- 3306:3306
restart: always
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
timeout: 20s
retries: 10
app:
image: shop-keeper
container_name: shop-keeper-app
build:
context: .
dockerfile: Dockerfile
ports:
- 8080:8080
depends_on:
mysql-db:
condition: service_healthy
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-db:3306/shopkeeper?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: vikas1234
Your config looks nice, I would just recommend:
Remove links: db. It has no value in user-defined bridge networking
Remove port exposing for db unless you want to connect from outside docker-compose - all ports are exposed automatically inside user-defined bridge network.
I think the problem is that database container takes more time to start than web. depends_on just controls the order, but does not guarantee you database readiness. If possible, set several connection attempts or put socket-wait procedure in your web container.

How to make Spring boot with Redis Sentinel work with Docker

I am trying to set up a Spring boot application with Redis Sentinel 3.2.11 using docker. However I am getting
Caused by: io.netty.channel.ConnectTimeoutException: connection timed out: /172.27.0.2:6379
My docker compose configuration
version: '3.1'
services:
master:
image: redis:3
container_name: redis-master
hostname: host_dev
networks:
- docker_dev
slave:
image: redis:3
command: redis-server --slaveof redis-master 6379
hostname: host_dev
links:
- master:redis-master
container_name: redis-slave
networks:
- docker_dev
sentinel:
build: sentinel
environment:
- SENTINEL_DOWN_AFTER=5000
- SENTINEL_FAILOVER=5000
- MASTER_NAME=mymaster
hostname: host_dev
image: sentinel:3
links:
- master:redis-master
- slave
container_name: sentinel
ports:
- "26379:26379"
networks:
- docker_dev
networks:
docker_dev:
Docker file
FROM redis:3
EXPOSE 26379
ADD sentinel.conf /etc/redis/sentinel.conf
RUN chown redis:redis /etc/redis/sentinel.conf
ENV SENTINEL_QUORUM 2
ENV SENTINEL_DOWN_AFTER 30000
ENV SENTINEL_FAILOVER 180000
COPY sentinel-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/sentinel-entrypoint.sh
ENTRYPOINT ["sentinel-entrypoint.sh"]
Spring configuration in application.properties:
redis.cluster.name=mymaster
redis.sentinel.nodes=localhost:26379
redis.timeout=2000
Issue:
The spring boot app(run from outside docker-machine) is able to connect with Sentinel node. The sentinel node provides the master information with IP 172.27.0.2 i.e docker n/w IP. The spring boot app tries to connect with redis-master at IP 172.27.0.2 and fails as the IP is not visible outside the docker machine.
Possible fix:
How can I make sentinel node provide an master IP as localhost instead of internal docker-machine n/w ip?

Categories