Connecting Spring Cloud Applications in Docker Container - spring

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.

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...*

Cannot run docker-compose.yml (throw image issues) in my Spring Boot App

I have a problem about running docker-compose.yml in my Spring Boot app.
When I run this command (docker-compose up -d), I got an issue in image part.
I tried to handle with solving this issue but I couldn't do that.
How can I fix it?
Here is my issue shown below.
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
Here is my project : My Project
Here is my docker-compose.yml shown below.
version: '3.8'
services:
logstash:
image: docker.elastic.co/logstash/logstash:7.15.2
user: root
command: -f /etc/logstash/conf.d/
volumes:
- ./logstash/:/etc/logstash/conf.d/
ports:
- "5000:5000"
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:7.15.2
user: root
volumes:
- ./kibana/:/usr/share/kibana/config/
ports:
- "5601:5601"
depends_on:
- elasticsearch
entrypoint: ["./bin/kibana", "--allow-root"]
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.15.2
user: root
volumes:
- ./elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
ports:
- "9200:9200"
- "9300:9300"
environment:
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
app:
image: 'springbootelk:latest'
build:
context: .
container_name: SpringBootElk
depends_on:
- db
- logstash
ports:
- '8077:8077'
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/springbootexample?useSSL=false&serverTimezone=Turkey
- SPRING_DATASOURCE_USERNAME=springexample
- SPRING_DATASOURCE_PASSWORD=111111
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
db:
container_name: mysql-latest
image: 'mysql:latest'
ports:
- "3306:3306"
restart: always
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes:
- db-data:/var/lib/mysql
# Volumes
volumes:
db-data:
There are several issues, why it doesn't work.
First thing - your tests aren't set up properly. Application tries to connect to database in the test stage. But during the test stage there is no any running containers yet. You can set it up properly, or remove MainApplicationTests class from the test directory, or by switching off your tests execution, just by adding -Dmaven.test.skip in Dockerfile for the mvnw package command. After it your image will build properly.
Second thing, you need to allow public key retrieval for your application. To do that, you can add allowPublicKeyRetrieval=true to your jdbc url. You can read more about it here: Connection Java - MySQL : Public Key Retrieval is not allowed.
These steps will allow your application to start (at least it will resolve database connectivity problems). But, I have found another issue. You set in your application configuration context-path equal to /api. Also you added #RequestMapping("/api") for your PersonController. And to access the list of persons, you will need to use the following url: http://localhost:8077/api/api/persons. Probably, it is not what you wanted. To fix it, you can remove it from any place.

Microservice not able to connect to AXON Server running as docker image

I have discovery service: https://github.com/Naresh-Chaurasia/API-MicroServices-Kafka/tree/master/Microservices-CQRS-SAGA-Kafka/DiscoveryService
I have product service: https://github.com/Naresh-Chaurasia/API-MicroServices-Kafka/tree/master/Microservices-CQRS-SAGA-Kafka/ProductsService
Following is my docker-compose.yml file: https://github.com/Naresh-Chaurasia/API-MicroServices-Kafka/tree/master/Microservices-CQRS-SAGA-Kafka/docker-compose.yml
version: "3.8"
services:
axon-server:
image: axoniq/axonserver
container_name: axon-server
ports:
- 8124:8124
- 8024:8024
networks:
- axon-demo
discovery-service:
build:
context: ./DiscoveryService
container_name: discovery-service
ports:
- 8010:8010
networks:
- axon-demo
networks:
axon-demo:
driver: bridge
When i run the following command docker-compose up, I get axon-server and discovery-service running.
I now run ProductService using the following file src/main/java/com/appsdeveloperblog/estore/ProductsService/ProductsServiceApplication.java which is under https://github.com/Naresh-Chaurasia/API-MicroServices-Kafka/tree/master/Microservices-CQRS-SAGA-Kafka/ProductsService.
It works fine.
The problem start when I try to run ProductService as a microservice, and it fails to connect to axon server. To do that I modify the docker-compose.yml as follows:
version: "3.8"
services:
axon-server:
image: axoniq/axonserver
container_name: axon-server
ports:
- 8124:8124
- 8024:8024
networks:
- axon-demo
discovery-service:
build:
context: ./DiscoveryService
container_name: discovery-service
ports:
- 8010:8010
networks:
- axon-demo
product-service:
build:
context: ./ProductsService
ports:
- 8090:8090
depends_on:
- axon-server
- discovery-service
networks:
- axon-demo
networks:
axon-demo:
driver: bridge
Now if I try to run docker-compose up, I get the following error:
product-service_1 | 2021-08-20 03:06:27.973 INFO 1 --- [#29db04f6c0a4-0] i.a.a.c.impl.AxonServerManagedChannel : Requesting connection details from localhost:8124
product-service_1 | 2021-08-20 03:06:30.004 WARN 1 --- [#29db04f6c0a4-0] i.a.a.c.impl.AxonServerManagedChannel : Connecting to AxonServer node [localhost:8124] failed: UNAVAILABLE: io exception
I have gone through the following link, Spring Boot Microservices are unable to connect to Axon Server, which looks like similar problem but still not able to fix my problem.
Please guide.
Thanks.
I made the following changes and it works fine now.
In the file ProductsService\src\main\resources\application.properties
Old Entry: eureka.client.serviceUrl.defaultZone = http://localhost:8010/eureka
New Entry: eureka.client.serviceUrl.defaultZone = http://discovery-service:8010/eureka
Added the following line in the above file: axon.axonserver.servers=axon-server:8124
In the File: Microservices-CQRS-SAGA-Kafka\docker-compose.yml
Old Entry: version: "3.8"
New Entry: version: "2"
Added following code in yml file
product-service:
build:
context: ./ProductsService
ports:
- 8090:8090
networks:
- axon-demo
I have also checked in the code in git. The micro services can talk to each other, and connect to axon server and the problem reported earlier is resolved.
Thanks.
Just a thought.
Try to add to each service in application.properties
axon.axonserver.servers=localhost:8124
and to each service which connects to axon-server in docker-compose.yml
in environment variables section
axon-server:
image: axoniq/axonserver
container_name: axon-server
ports:
- 8124:8124
- 8024:8024
product-service:
...
environment:
AXON_AXONSERVER_SERVERS: axon:8124

Spring boot microservices and Docker, unable to connect to database

I'm writing a test app in microservices to learn Spring Boot. I'm done with the app and looking to deploy it on AWS using docker/docker-compose to host each microservices.
I'm unable to connect any of the Spring Boot instances to their Mysql database. I've been stuck on it for a few days and I can't see what's wrong.
Here is my docker-compose.yml
version: "3.3"
services:
card_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "cards"
ports:
- "33061:3306"
auth_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "auth"
ports:
- "33062:3306"
market_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "market"
ports:
- "33063:3306"
user_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "user"
ports:
- "33064:3306"
adminer:
image: adminer
restart: always
ports:
- 8000:8080
user:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/services/user/target/cardmarket-user-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
depends_on:
- "user_mysql"
card:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/services/card/target/cardmarket-card-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
depends_on:
- "card_mysql"
market:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/services/market/target/cardmarket-market-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
depends_on:
- "market_mysql"
proxy:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/zuul-proxy/target/zuul-proxy-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
auth:
image: "openjdk:11"
restart: always
entrypoint: java -jar /app/zuul-proxy/zuul-proxy-0.0.1-SNAPSHOT.jar
volumes:
- ./:/app
depends_on:
- "auth_mysql"
Here are each of my spring datasource settings:
user application.properties
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://user_mysql:3306/user
spring.datasource.initialization-mode=always
spring.datasource.username=root
spring.datasource.password=root
market application.properties
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://market_mysql:3306/market
spring.datasource.initialization-mode=always
spring.datasource.username=root
spring.datasource.password=root
Auth application.properties
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://auth_mysql:3306/auth
spring.datasource.initialization-mode=always
spring.datasource.username=root
spring.datasource.password=root
Card application.properties
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://card_mysql:3306/cards
spring.datasource.initialization-mode=always
spring.datasource.username=root
spring.datasource.password=root
I'm sure it is something small I'm missing or misunderstood, but I can't figure out what.
Edit 1
I ran a couple more tests but still wasn't able to figure out what's wrong.
I commented out everything but the card and card_mysql containers. The spring boot instance throw an exception for every configuration possible (using docker dns name, localhost, shared and network ip), none of them seems to work.
The two containers do communicate, I can ping between them using the dns name.
I'm using docker-desktop with wsl and deploy my containers on a wsl Ubuntu 20.04. I haven't tried on an actual Linux machine.
I've also tried to make the spring boot instance wait for the mysql one using wait-for-it.sh, it does wait correctly but the exception still occurs.
Here is parts of the exception spring boot triggers:
2021-05-16 12:23:48.948 INFO 1 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-05-16 12:23:50.277 ERROR 1 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization.
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
...
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
...
Caused by: java.net.ConnectException: Connection refused (Connection refused)
Edit 2
I tried having just one instance of spring boot and mysql and linking them using a network, unfortunately the exception still triggers. The two containers still pings. Here is the docker-compose I used for this test:
version: "3.9"
services:
card_mysql:
image: "mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "cards"
networks:
- "card_network"
card:
image: "openjdk:11"
restart: always
entrypoint: ["/app/wait-for-it.sh", "card_mysql:3306", "--", "java", "-jar", "/app/services/card/target/cardmarket-card-0.0.1-SNAPSHOT.jar"]
# entrypoint: ["/app/wait-for-it.sh", "card_mysql:3306", "--", "ping", "card_mysql"]
volumes:
- ./:/app
depends_on:
- "card_mysql"
networks:
- "card_network"
networks:
card_network: {}
Hi Spinarial please add network and gather it all in one network
version: "3.4"
services:
springMvcRestApi:
image: springbootproject:0.0.1
container_name: app
networks:
- postgres
ports:
- 8085:8085
depends_on:
- postgres
- pgadmin
links:
- postgres
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/reactiveDbcd?createDatabaseIfNotExist=true
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: 12345
postgres:
container_name: postgres
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: 12345
PGDATA: /data/postgres
volumes:
- postgres:/data/postgres
expose:
- 5432
ports:
- 5432:5432
networks:
- postgres
restart: unless-stopped
pgadmin:
container_name: pgadmin_container
image: dpage/pgadmin4
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4#pgadmin.org}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
PGADMIN_CONFIG_SERVER_MODE: 'False'
volumes:
- pgadmin:/root/.pgadmin
ports:
- "${PGADMIN_PORT:-80}:80"
networks:
- postgres
restart: unless-stopped
networks:
postgres:
driver: bridge
volumes:
postgres:
pgadmin:

Access to local database denied through docker container

I am having a problem connecting my compiled Spring-Boot app to the database that I have running on another container on my server.
I have tried different configurations, changing from localhost to the IP address of my server for the connection. I also double checked that the credentials matched by logging in via Adminer. Finally, I did a rebuild of the compose and image files several times to ensure that I have all the latest versions.
Compose file:
version: '3.1'
services:
db:
image: mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: mypassword
MYSQL_DATABASE: marketingappdb
ports:
- "3306:3306"
expose:
- 3306
volumes:
- ./mariadbvolume:/var/lib/mariadb
networks:
- marketingapp
adminer:
image: adminer
restart: always
ports:
- "8086:8080"
expose:
- 8086
depends_on:
- db
networks:
- marketingapp
springserver:
image: marketingapp
restart: always
ports:
- "8091:8091"
expose:
- 8091
depends_on:
- db
networks:
- marketingapp
networks:
marketingapp:
Spring Server Image:
FROM openjdk:latest
COPY /marketing-app-final.jar .
EXPOSE 8091
ENTRYPOINT ["java", "-jar", "marketing-app-final.jar"]
Application properties for Spring:
server.port = 8091
spring.datasource.url=jdbc:mariadb://0.0.0.0:3306/marketingappdb
spring.datasource.username=root
spring.datasource.password=mypassword
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
I can connect from my PC to the database using the app from the remote same configuration (obviously replacing localhost with the IP) and don't see why I shouldn't be able to do the same from the actual server. Thanks in advance for any help!
Use the docker dns to connect your spring App to the mariabd:
jdbc:mariadb://db:3306/marketingappdb
Just a few other hints: you don't need to expose port 3306, you already bind it to 3306 on Host (if you just want to use it from within the docker Services you don't need to bind/expose it at all). And the mariabd persistent storage is var/lib/mysql and not var/lib/mariadb

Resources