docker application not communicate with docker mysql container - spring-boot

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

Related

Trouble with connecting PostgreSQL in docker-compose

I am trying to create a Laravel project on Docker with a PostgreSQL database locally. The structure of my project is described below:
nginx
conf.d
default.conf
php
Dockerfile
src
Laravel Project
docker-compose-yml
I can run the project successfully on the 8080 port, but I'm having trouble connecting to PostgreSQL.
Here is my docker-compose.yml:
version: '3.8'
networks:
laravel:
services:
nginx:
image: nginx:alpine
command: nginx -g "daemon off;"
container_name: nginx
ports:
- "8080:80"
volumes:
- ./src:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d
depends_on:
- php
networks:
- laravel
php:
build:
context: ./php
dockerfile: Dockerfile
volumes:
- ./src:/var/www
ports:
- "9000:9000"
networks:
- laravel
db:
container_name: postgres
image: postgres
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=root
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_DB=expense
volumes:
- ./postgres:/var/lib/postgresql/data"
ports:
- "5446:5432"
restart: always
networks:
- laravel
In case you want to know, here is the Dockerfile for PHP:
FROM php:8.0.3-fpm
RUN docker-php-ext-install pdo
And also I want to mention the .env that is used by Laravel project:
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=postgres
with this configuration first I've run the docker-compose build and after running the docker-compose up I'm getting the below result for Postgres:
And when I want to reach 127.0.0.1:5432 there's nothing to show me. How can I solve this problem?
In your service db your POSTGRES_DB=expense set the default database name to expense (doc)
So your .env should use DB_DATABASE=expense and not postgres
And a last thing I am not sure about (because I can't find the documentation about it) is your DB_HOST: I don't know if you should use the container_name -> postgres or the service_name -> db, I think it's the service_name so db in your case

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

How to access an external server folder from a spring boot docker container?

I'm using docker-compose to run spring boot application inside a docker container. A spring boot uses embedded tomcat to run.
There is an external folder on a server (/opt/cp/uploads) with images which I would like to access from a spring boot docker container.
Within the docker-compose.yaml file there are following containers defined:
nginx
mysql
springboot-app
nginx and CloudFlare redirect the domain to the spring app on the port 8080.
I'd like to access images like this:
https://domainname.com/uploads/imageName.png
Using tomcat this was done in server.xml:
<Context docBase="/opt/uploads" path="/uploads"/>
but this option is obviously not available via application.properties with embedded tomcat.
How does one come about this?
My docker-compose.yaml:
version: '3.8'
services:
nginx:
container_name: some-nginx
hostname: nginx
image: nginx:1.19.2-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
restart: unless-stopped
network_mode: host
mysqldb:
image: mysql:8.0.20
hostname: mysqldb
container_name: cp-mysqldb
environment:
- MYSQL_ROOT_PASSWORD=pass1234
- MYSQL_DATABASE=db_name
- MYSQL_USER=root
- MYSQL_PASSWORD=pass1234
ports:
- "3306:3306"
volumes:
- cp-mysqldb-data:/opt/mysql
restart: unless-stopped
springboot-app:
image: openjdk:8
hostname: cp
container_name: cp-springboot
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysqldb:3306/db_name?autoReconnect=true&useSSL=false&useUnicode=yes&characterEncoding=UTF-8&characterSetResults=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
ports:
- "8080:8080"
depends_on:
- mysqldb
volumes:
- cp-springboot-data:/opt/cp
- ./target/cp-springboot-0.0.1-SNAPSHOT.war:/ROOT.war
command: ["java", "-jar",
"-Dspring.profiles.active=prod",
"ROOT.war"]
restart: always
volumes:
cp-springboot-data: {
}
cp-mysqldb-data: {
}
Maybe better use Tomcat for docker image and not OpenJDK.
That way you can setup your Tomcat configuration for the external path
Take a look here: https://medium.com/#iamvickyav/deploying-spring-boot-war-in-tomcat-based-docker-2b689b206496
Actually, this option IS available via application.properties with embedded tomcat:
spring.mvc.static-path-pattern=/uploads/**
spring.resources.static-locations=file:/opt/uploads

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