Could not connect to docker redis container from docker application container with docker-compose - spring

I faced the problem with docker-compose.
I tried a lot of themes here on StackOverflow, but it seems that i tried almost everything, but anyway my app does not work.
I have a docker-compose multiapp configuration with:
application
mysql
redis
The point is that when mysql and redis containers are up, my application that is in container throws an error:
org.springframework.context.ApplicationContextException: Failed to start bean 'springSessionRedisMessageListenerContainer';
nested exception is
org.springframework.data.redis.listener.adapter.RedisListenerExecutionFailedException: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis;
nested exception is
io.lettuce.core.RedisConnectionException: Unable to connect to localhost/<unresolved>:6379;
nested exception is
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis;
nested exception is
io.lettuce.core.RedisConnectionException: Unable to connect to localhost/<unresolved>:6379
However, when i launch my application in IDE instead of docker container, everything works well!
so it seems that the problem in Docker, i.e. in container settings. But, on the other hand, the container's application successfully connects to mysql, and the problem is only about redis container.
i'm confused. moreover, i wonder what means in localhost/<unresolved>:6379.
the docker-compose file looks like this:
version: '3.9'
services:
mysql-docker:
container_name: mysql-docker
image: mysql:8.0.31
restart: always
ports:
- "3306:3306"
volumes:
- ${MYSQL_DATA}:/var/lib/mysql
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
env_file:
- ./.env
healthcheck:
test: mysql sys --user=${MYSQL_ROOT_USER} --password=${MYSQL_ROOT_PASSWORD} --silent --execute "SELECT 1;"
interval: 3s
timeout: 10s
retries: 10
networks:
- my-network
redis-docker:
depends_on:
mysql-docker:
condition: service_healthy
container_name: redis-docker
image: redis:7.0.5
restart: always
ports:
- 6379:6379
command: "redis-server --loglevel warning --port ${SPRING_REDIS_PORT} --requirepass ${SPRING_REDIS_PASSWORD}"
volumes:
- ${SPRING_REDIS_DATA}:/var/lib/redis
env_file:
- ./.env
healthcheck:
test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
interval: 3s
timeout: 10s
retries: 10
networks:
- my-network
app:
depends_on:
mysql-docker:
condition: service_healthy
redis-docker:
condition: service_healthy
links:
- redis-docker
- mysql-docker
build: ./
restart: on-failure
env_file:
- ./.env
volumes:
- ${SPRING_M2_BUILD_DATA}:/root/.m2
stdin_open: true
tty: true
networks:
- my-network
networks:
my-network:
driver: bridge
Dockerfile for application is not interesting, there is just standart FROM, COPY and RUN gradle clean build.
Properties for redis in application.properties:
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=verySecuredPassword
in .env file (it is needed for potential kubernetes):
SPRING_REDIS_PASSWORD=verySecuredPassword
SPRING_REDIS_PORT=6379
SPRING_REDIS_URL=redis://redis-docker:${SPRING_REDIS_PORT}
There are no other config files. As i got, there is no need for them - the application works well when it is not in container.
Moreover, it seems that the problem is not about binding redis to 0.0.0.0 (btw i tried that too - didn't work) - because it refuses only 'dockerized' connections somehow. But i could be wrong, ofc.
I tried redis-cli ping from windows powershell - and got pong. So, the redis obiously works, works correctly (becauseof correctness of application launched into IDE) and accepts connections.
What am i missing?

Related

docker application not communicate with docker mysql container

I just encountered a problem. I am dockerizing a springboot application with MySQL as a database it is perfectly working in a local setup. But when I try to dockerize the application using docker-compose, MySQL container is working fine and is accessible in my workbench but my application is not able to access it throwing the communication link failure.
This is the compose file I am using:
version: "3.8"
services:
mysqldb:
image: mysql:5.7
restart:unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=baskartest
ports:
- 3307:3306
volumes:
- db:/var/lib/mysql
app:
depends_on:
- mysqldb
build: ./bezkoder-app
restart:on-failure
env_file: ./.env
ports:
- 8084:8080
environment:
SPRING_APPLICATION_JSON: '{
"spring.datasource.url" : "jdbc:mysql://mysqldb:3306/baskartest?useSSL=false",
"spring.datasource.username" : "root",
"spring.datasource.password" : "root",
"spring.jpa.properties.hibernate.dialect" : "org.hibernate.dialect.MySQL5InnoDBDialect",
"spring.jpa.hibernate.ddl-auto" : "update"
}'
volumes:
- .m2:/root/.m2
stdin_open: true
tty: true
MySQL is working fine but my app in services is not able to communicate with it.
Here is what I see:
Any help would be appreciated!
I have done small changes in docker-compose.yml file, please use this one. It is working fine.
version: "3.8"
services:
mysqldb:
image: mysql:5.7
container_name: MYSQL_DB
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=baskartest
ports:
- 3307:3306
app:
build: ./bezkoder-app
restart: on-failure
ports:
- 8084:8080
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://MYSQL_DB:3306/baskartest
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
depends_on:
- mysqldb
In my short experience with Docker and containers communicating with eachother, I've found that localhost configuration URL's aren't working. Because one container can't communicatie with another container using just localhost:[PORT].
A lazy way for me to fix this is to work out a static IP address of the machine the containers are running on. Then use this (local) IP address instead of localhost to define the endpoint of the database.
In my situation with Redis I'm doing it like this:
return new LettuceConnectionFactory(new RedisStandaloneConfiguration("192.168.1.201", 6379));
In your situation, you might want to use a Datasource URL like this:
- SPRING_DATASOURCE_URL=jdbc:mysql://[STATIC_IP_OF_MACHINE]:3306/baskartest
*i.e. ...192.168.1.100:3306/baskartest...*

No resolvable bootstrap urls given in bootstrap.servers on maven install

I am building up a jar file for my spring boot microservice, but upon maven install i am getting the error as stated below.
Caused by: org.apache.kafka.common.config.ConfigException: No resolvable bootstrap urls given in bootstrap.servers
at org.apache.kafka.clients.ClientUtils.parseAndValidateAddresses(ClientUtils.java:89) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.ClientUtils.parseAndValidateAddresses(ClientUtils.java:48) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.KafkaConsumer.<init>(KafkaConsumer.java:730) ~[kafka-clients-3.1.1.jar:na]
my docker-compose file for the application is
version: '2'
services:
zookeeper:
image: confluentinc/cp-zookeeper:latest
restart: always
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
ports:
- 2181:2181
networks:
- app-network
kafka:
image: confluentinc/cp-kafka:latest
container_name: kafka
restart: always
depends_on:
- zookeeper
ports:
- 9092:9092
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
networks:
- app-network
mongodb:
image: mongo:latest
restart: always
container_name: mongodb
networks:
- app-network
ports:
- 27017:27017
matching-engine-helper:
image: matching-engine-helper:latest
restart: always
container_name: "matching-engine-helper"
networks:
- app-network
ports:
- 9192:9192
depends_on:
- mongodb
- zookeeper
- kafka
matching-engine-core:
image: matching-engine-core:latest
restart: always
container_name: "matching-engine-core"
networks:
- app-network
ports:
- 9191:9191
depends_on:
- matching-engine-helper
- zookeeper
- kafka
- mongodb
networks:
app-network:
driver: bridge
and the application.yml is
spring:
data:
mongodb:
database: matching-engine-mongodb
host: mongodb
port: 27017
kafka:
bootstrap-servers: kafka:9092
server:
port: 9192
let me know if i need some environment variable's configuration here. as its running fine on local environment on local host but not on docker containers as i am unable to make a jar out of it.
Assuming mvn install is running on your host, then your host doesn't know how to resolve kafka as a DNS name running in a container. It that's what you wanted, then you should rename your file to application-docker.yml and use Spring profiles to properly override any defaults when you actually do run your code in a container. In your case, you would need to have localhost:29092 for Kafka, and similarly use localhost:27017 for Mongo in your default application.yml. You can also use environment variables for those two properties rather than hard-code them.
Or, if mvn install is running in a Docker layer itself, then that is completely isolated from other Docker networks. You can pass --network flag to docker build, though.
Assuming you don't want to mvn install -DskipTests, ideally, your tests do not rely on external services to be running. If you want to run a Kafka unit test, which is failing to connect, then you should either mock that, or using Spring-Kafka's EmbeddedKafka for integration-tests.
Worth mentioning that Spring boot has a Maven plugin for building Docker images, and it doesn't need a JAR to do so.

Dockerizing SpringBoot Mongo Exception opening socket

I am trying to dockerize my spring boot and mongo.
This is my application.yml
spring:
application:
name: service-app
data:
mongodb:
uri: mongodb://localhost:27017/user
I have found this to be recommended in other posts.
The error I get is:
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:70) ~.
[mongodb-driver-core-4.1.1.jar:na]
version: '3'
services:
mongo:
image: library/mongo:latest
container_name: mongo
restart: always
ports:
- 27017:27017
network_mode: host
volumes:
- $HOME/mongo:/data/db
healthcheck:
test: "exit 0"
user-service:
build:
context: .
dockerfile: Dockerfile
image: user-service
depends_on:
- mongo
network_mode: "host"
hostname: localhost
restart: always
ports:
- 8082:8082
healthcheck:
test: "exit 0"
FROM openjdk:8-jdk-alpine
ADD ./target/demo-0.0.1-SNAPSHOT.jar /usr/src/user-service-0.0.1-SNAPSHOT.jar
WORKDIR usr/src
ENTRYPOINT ["java -Djdk.tls.client.protocols=TLSv1.2","-jar", "user-service-0.0.1-SNAPSHOT.jar"]
It seems to be a common problem for noobsters, I couldn't solve it with what was on the internet already.
The problem is in not building the url properly.
By the information I gave, I should have gotten a proper answer, instead I got -1.
Some people are true trolls with privileges.
uri: mongodb://mongo/user
I feel like it became a gamble on Stackoverflow, depends on the type of people crossing over your question.

Spring boot + docker + rest template connection refused

I have two services, spring boot docker and when I try communication with rest template I got java.net.ConnectException: Connection refused (Connection refused)
url is http://localhost:8081/api/v1/package/250Mbps
Service 1 docker-compose.yml:
product_catalogue_service:
image: openjdk:8-jdk-alpine
ports:
- "8081:8081"
volumes:
- .:/app
working_dir: /app
command: ./gradlew bootRun
restart: on-failure
Service 2 docker-compose.yml:
order_service:
image: openjdk:8-jdk-alpine
ports:
- "8083:8083"
volumes:
- .:/app
working_dir: /app
command: ./gradlew bootRun
restart: on-failure
Rest template URL, and it is working when I run project 2 from the IntelliJ:
http://localhost:8081/api/v1/package/250Mbps
When I run docker ps, name of first service is:
productcatalogueservice_product_catalogue_service_1
I tried to use that instead of localhost - unknown host exception.
I tried "product_catalogue_service_1" instead, also unknown host exception,
and finally I tried "product_catalogue_service" also unknown host exception.
Any idea?
By default, docker-compose creates a network between your containters and assign the serivce name as de host name.
So, you can reach the product_catalog_service from order_service like so: http://product_catalog_service:8081/api/v1/package/250Mbps
Now, from your post it seems that you have two different docker-compose.yml files, one for each service. In this case, each container is living in its own network (created by docker-compose) and they can't see each other, at least by default.
Honestly, I've never try to connect two containers created from two different docker-compose files. I always create one docker-compose.yml file, put there all my services and let docker-compose manage the network between them.
Using one docker-compose.yml
version: ...
services:
product_catalogue_service:
image: openjdk:8-jdk-alpine
ports:
- "8081:8081"
volumes:
- .:/app
working_dir: /app
command: ./gradlew bootRun
restart: on-failure
order_service:
image: openjdk:8-jdk-alpine
ports:
- "8083:8083"
volumes:
- .:/app
working_dir: /app
command: ./gradlew bootRun
restart: on-failure
One last thing, this answer explains in great detail why localhost:8081 is not working from your order_service container.

Connecting Spring Cloud Applications in Docker Container

I am attempting to host a Spring Cloud application in Docker containers.The underlying exception is as follows:
search_1 | Caused by: java.lang.IllegalStateException: Invalid URL: config:8888
I understand the reason is because of the URL specified in my config server.
spring.application.name=inventory-client
#spring.cloud.config.uri=http://localhost:8888
spring.cloud.config.uri=config:8888
On my development machine, I am able to use localhost. However, based on a past question (relating to connecting to my database), I learned that localhost is not appropriate in containers. For my database, I was able to use the following:
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=false
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://db:5432/leisurely_diversion
#spring.datasource.url=jdbc:postgresql://localhost:5000/leisurely_diversion
spring.datasource.driver-class-name=org.postgresql.Driver
but this obviously did not work as expected for the configuration server.
My docker-compose file:
# Use postgres/example user/password credentials
version: '3.2'
services:
db:
image: postgres
ports:
- 5000:5432
environment:
POSTGRES_PASSWORD: example
volumes:
- type: volume
source: psql_data
target: /var/lib/postgresql/data
networks:
- app
restart: always
config:
image: kellymarchewa/config_server
networks:
- app
volumes:
- /root/.ssh:/root/.ssh
restart: always
search:
image: kellymarchewa/search_api
networks:
- app
restart: always
ports:
- 8082:8082
depends_on:
- db
- config
- inventory
inventory:
image: kellymarchewa/inventory_api
depends_on:
- db
- config
ports:
- 8081:8081
networks:
- app
restart: always
volumes:
psql_data:
networks:
app:
Both services are running under the same user defined network; how I allow the services to find the configuration service?
Thanks.

Resources