Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Fa - spring

I am developing a web application by using the Spring Boot, Spring Cloud Config and Docker. There are 3 projects. One is springboot web, Spring Cloud Config Server and MySql Database. I have use the Spring Boot Web with Themeleaf. It's basically perform a CRUD operation. In the development phase it's working fine. But when I deploy it in the Docker
Spring-Boot webapp container(springboot-thymeleaf-web-crud) is giving me the following error--
APPLICATION FAILED TO START
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
I have created 3 container on Docker Compose file.
version: '3'
services:
springboot-thymeleaf-web-crud:
image: numery/springboot-thymeleaf-web-crud:latest
networks:
- employee-network
ports:
- 8080:8080
depends_on:
- employee-database
- spring-cloud-config-server-employee
spring-cloud-config-server-employee:
image: numery/spring-cloud-config-server-employee:latest
networks:
- employee-network
ports:
- 8888:8888
employee-database:
image: mysql:5
networks:
- employee-network
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=employee_directory
volumes:
- /home/numery/Docker-Database/employee_directory:/var/lib/mysql
networks:
employee-network:
SpringBoot Web Application.properties is given below
spring.application.name=employee-service-mysql
server.port=8080
spring.cloud.config.uri=http://spring-cloud-config-server-
employee:8888
spring.profiles.active=dev
SpringBoot Config Server is providing the following properties--
spring.datasource.url: jdbc:mysql://employee-
database:3306/employee_directory?
useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username: root
spring.datasource.password: rootpassword
spring.datasource.validationQuery: SELECT 1
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.tomcat.max-wait: 20000
spring.tomcat.max-active: 50
spring.tomcat.max-idle: 20
spring.tomcat.min-idle: 15
spring.jpa.properties.hibernate.dialect:
org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql: true
spring.jpa.format-sql: true
spring.jpa.database: MYSQL
spring.jpa.hibernate.ddl-auto: create
Out of these 3 containers Mysql and Spring Cloud Config container is working fine. But for the Spring Boot Webapp(springboot-thymeleaf-web-crud) is exiting by giving the error above.
Note: I use the same datasouce(Spring Data JPA) configuration on some other SpringBoot Rest API. Which are working fine. But this is the first time I am using SpringBoot Web. Do I need to explicitly define any configuration on the data-source.
Please help!!

The datasource URL, that is spring.datasource.url: jdbc:mysql://employee- may be wrong.
OR Should add your datasource url to your Application.properties file
The url should be in the format jdbc:oracle:thin:#hostname:portNumber/schemaName
For further details and clarification, Not using the hostname and port in jdbc url

I perform the following task to solve the problem--
1) We should have up and running the mysql
container.
2) Inspect mysql container which ip running--
docker inspect mysqlcontainer | grep IP
3) Add the IP of that mysql container to my
springboot web app--
"spring.datasource.url:
jdbc:mysql://172.20.0.2:3306/employee_directory?
useSSL=false&serverTimezone
=UTC&useLegacyDatetimeCode=false"
4) run mvn clean, mvn install and build the
SpringBoot Web image.
5) If we down the container we need to perform the
same task again. Because each time Mysql
container obtain the different ip.

Related

Connecting to a Mongo container from Spring container

I have a problem here that I really cannot understand. I already saw few topics here with the same problem and those topics was successfully solved. I basically did the same thing and cannot understand what I'm doing wrong.
I have a Spring application container that tries to connect to a Mongo container through the following Docker Composer:
version: '3'
services:
app:
build: .
ports:
- "8080:8080"
links:
- db
db:
image: mongo
volumes:
- ./database:/data
ports:
- "27017:27017"
In my application.properties:
spring.data.mongodb.uri=mongodb://db:27017/app
Finally, my Dockerfile:
FROM eclipse-temurin:11-jre-alpine
WORKDIR /home/java
RUN mkdir /home/java/bar
COPY ./build/libs/foo.jar /home/java/bar/foo.jar
CMD ["java","-jar", "/home/java/bar/foo.jar"]
When I run docker compose up --build I got:
2022-11-17 12:08:53.452 INFO 1 --- [null'}-db:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server db:27017
Caused by: java.net.UnknownHostException: db
Running the docker compose ps I can see the mongo container running well, and I am able to connect to it through Mongo Compass and with this same Spring Application but outside of container. The difference running outside of container is the host from spring.data.mongodb.uri=mongodb://db:27017/app to spring.data.mongodb.uri=mongodb://localhost:27017/app.
Also, I already tried to change the host for localhost inside of the spring container and didnt work.
You need to specify MongoDB host, port and database as different parameters as mentioned here.
spring.data.mongodb.host=db
spring.data.mongodb.port=27017
spring.data.mongodb.authentication-database=admin
As per the official docker-compose documentation the above docker-compose file should worked since both db and app are in the same network (You can check if they are in different networks just in case)
If the networking is not working, as a workaround, instead of using localhost inside the spring container, use the server's IP, i.e, mongodb://<server_ip>:27017/app (And make sure there is no firewall blocking it)

How can I dockerize my springboot application which has multiple datasources?

I have a springboot application which uses a postgresql database and a mongoDB database , I have been able to correctly configure them but now when I want to dockerize my application to later deploy it on a Kubernetes cluster, I am completely clueless. Most of the youtube tutorials and articles are on how to dockerize simple springboot applications or springboot applications that use only one database, thus any input on how I can proceed to dockerize my application would be really appreciated!
Edit:
I am following this tutorial -
https://www.section.io/engineering-education/running-a-multi-container-springboot-postgresql-application-with-docker-compose/
Here in the docker-compose.yml file-
version: '3.1'
services:
API:
image: 'blog-api-docker.jar'
ports:
- "8080:8080"
depends_on:
PostgreSQL:
condition: service_healthy
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://PostgreSQL:5432/postgres
- SPRING_DATASOURCE_USERNAME=postgres
- SPRING_DATASOURCE_PASSWORD=password
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
PostgreSQL:
image: postgres
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=postgres
- POSTGRES_DB=postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
Only one postgreSQL datasource is defined ,in my project with a similar postgreSQL datasource as given in the tutorial I am also using a mongoDB database which is running on atlas.
I am also including my application.properties file for your reference-
spring.ds-psql.datasource.jdbcUrl=jdbc:postgresql://localhost:5432/devicestatspsql
spring.ds-psql.datasource.username=
spring.ds-psql.datasource.password=
spring.data.mongodb.users-mongo-atlas.uri=*mongodb database url here*
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
So I just need to know what changes are required in my docker-compose.yml file to accommodate this mongodb database in the docker image
You can use the Kubernetes Configmap and Secret as of now to store the configuration of your application.
Configmap and Secret are mostly for storing configurations like database connection strings, usernames, and passwords.
You can create different configuration maps as per requirement for Dev,Stag and Prod then inject the specific to your deployment so the application will get those values from either .env file or from OS environment.
Here's the reference article.

Cannot connect my springboot docker with my cassandra docker

I have some issues to dockerize my Spring boot Cassandra application.
When I use Idea to run my project it's work fine correctly but when I turn my application into a docker container I have this issues :
"RetryingCassandraClusterFactoryBean : All host(s) tried for query failed (tried: localhost/127.0.0.1:9042 (com.datastax.driver.core.exceptions.TransportException: [localhost/127.0.0.1:9042] Cannot connect))"
my application.properties:
spring.data.cassandra.keyspace-name=keyspace
spring.data.cassandra.contact-points=127.0.0.1
spring.data.cassandra.port=9042
spring.data.cassandra.schema-action=create_if_not_exists
server.port=8081
my cassandra :
cassandradb:
image: "cassandra:latest"
container_name: "cassandradb"
ports:
- "9042:9042"
- "7191:7191"
- "7001:7001"
- "9160:9160"
- "7000:7000"
environment:
CASSANDRA_CLUSTER: "myCluster"
CASSANDRA_ENDPOINT_SNITCH: "GossipingPropertyFileSnitch"
CASSANDRA_DC: "data"
CASSANDRA_LISTEN_ADDRESS: "auto"
photos:
image: "photos:latest"
container_name: "photo"
ports:
- "8081:8081"
links:
- "cassandradb"
Error happens, becouse your spring cant reach cassandradb. You should connect or via host ip, or usecassandradb` host, anc configure docker-compose.yml links part
I develop a simple example about the CRUD spring boot application by Cassandra.
You can check it in github. here are a few differences in the comparison of mine.

Docker image with Spring boot fails to connect to CloudSQL

I want to create web services with Spring boot, add it to docker image, connect to cloud sql and then run on Compute Engine.
I am using docker compose to combine the image for project and cloud sql proxy image. However, no matter what jdbc URL I give it fails to connect. Right now, I am trying all of this locally
I have tried following URLs:
1. spring.datasource.url=jdbc:mysql:///cloudsql/myinstancename/${MYSQL_DATABASE}
2. spring.datasource.url=jdbc:mysql://cloudsql/myinstancename/${MYSQL_DATABASE}
3. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/${MYSQL_DATABASE}
docker-compose.yml
version: '3'
services:
app:
image: appname
volumes:
- cloudsql:/cloudsql
depends_on:
- sql_proxy
ports:
- 8080:8080
# SQL proxy is built correctly, says
# Listening on /cloudsql/myinstancename for myinstancename
# sql_proxy_1 | Ready for new connections
sql_proxy:
environment:
- MYSQL_ROOT_PASSWORD=password!#
- MYSQL_DATABASE=appname
- MYSQL_USER=root
image: gcr.io/cloudsql-docker/gce-proxy:1.12
command:
/cloud_sql_proxy
-dir=/cloudsql
-instances=myinstancename # (I have added this correctly)
-credential_file=/root/keys/keyfile.json
volumes:
- E:\mykey.json:/root/keys/keyfile.json:ro
- cloudsql:/cloudsql
ports:
- 3306:3306
volumes:
# This empty property initializes a named volume.
cloudsql:
application.properties:
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql:///cloudsql/myinstancename/${MYSQL_DATABASE}
spring.datasource.username=${MYSQL_USER}
spring.datasource.password=${MYSQL_ROOT_PASSWORD}
spring.security.enabled=false
security.ignored=/**
Currently, you are using the Cloud SQL proxy in a sidecar pattern that is mounting a unix socket in /cloudsql/<INSTANCE_CONNECTION_NAME> that can be used to connect to your Cloud SQL instance. Unfortunately, most Java JDBC drivers don't support unix sockets. You can switch the Cloud SQL Proxy to provide a tcp socket instead with something like the following: "-instances=<INSTANCE_CONNECTION_NAME>=tcp:3306".
Alternatively, you can use the Cloud SQL JDBC Socket Factory. This is a Java library that allows you to create authenticated connections to a Cloud SQL instance, but doesn't require using the proxy.

Spring Boot, PostgreSQL, and Docker - Connection Refused whil Running in Container

I am attempting to build a "service" consisting of a Spring Boot application and PostgreSQL database. I have been able to access the database (running in a container) from the Spring Boot app while the Spring Boot application was running on my local machine. Now, when I attempt to move the Spring Boot application to a container, I am received the following error:
inventory_1 | 2018-01-20 18:43:06.108 ERROR 1 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection] with root cause
inventory_1 |
inventory_1 | java.net.ConnectException: Connection refused (Connection refused)
However, I am able to connect to DB from my local machine:
psql -h localhost -p 5000 -U kelly_psql -d leisurely_diversion
My application.properties file:
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=false
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://localhost:5432/leisurely_diversion
spring.datasource.username=kelly_psql
spring.datasource.password=pass
spring.datasource.driver-class-name=org.postgresql.Driver
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
inventory:
image: kellymarchewa/inventory_api
depends_on:
- db
ports:
- 8080:8080
networks:
- app
restart: always
volumes:
psql_data:
networks:
app:
My Dockerfile (from the Spring website)
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
I suspect the issue lies in a misunderstanding (on my part) of Docker or containers, but I am not sure. Any advice would be appreciated.
You are pointing your application towards localhost, but this is not shared between containers.
To access another container you have to refer to its hostname.
In your case, I understand that you want the inventory service to access the db service. So you should use the following datasource url:
spring.datasource.url=jdbc:postgresql://db:5432/leisurely_diversion
See this simple tutorial about connecting to a container from another container with docker compose: https://docs.docker.com/compose/gettingstarted/
Like in my case if you are using Docker Toolbox for windows 8.1 then you cannot use "localhost",
Instead you have to use docker machine ip;
host> docker-machine ip default
192.168.99.100
After that your url will look like;
spring.datasource.url=jdbc:postgresql://192.168.99.100:5432/bankdb
This will successfully connect to docker Postgres DB.
Cheers!!
Elaborating a little upon the answer given by ESala:
I agree, it is a networking issue and the given solution works fine, but you can also use localhost (e.g. if you really really want to), by switching to network host mode when running your containers (cf here). Like done here for nginx.
I'd say you won't want this most of the time, since it messes with the sandbox you gain. But the option exists.

Resources