Docker image with Spring boot fails to connect to CloudSQL - spring-boot

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.

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.

Connection refused to localhost:5432 through Docker Compose after already specifying the name of the service instead of localhost

I have a few microservices running under Docker. They are Zuul, Eureka, and a configuration server. These are working but when I start my authorization-service, it says I cannot connect to PostgreSQL.
version: '3'
services:
eureka-discovery:
...
zuul-gateway:
...
config:
...
postgres:
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: root
POSTGRES_DB: spring_microservices
ports:
- 5432:5432
authorization-service:
image: authorization-service:0.0.1
environment:
- eureka.client.serviceUrl.defaultZone=http://eureka-discovery:8761/eureka
- spring.cloud.config.uri=http://zuul-gateway:8765/config-service
- spring.datasource.url=jdbc:postgresql://postgres:5432/spring_microservices
depends_on:
- eureka-discovery
- zuul-gateway
- config
- postgres
ports:
- 1001:1001
What's confusing is that I am specifying postgres instead of localhost to make the connection, but the error continues to say "localhost". You see I override other properties the same way I do with spring.datasource.url and they work but this one.
org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
I attempted a few variations I could find around, such as using a different service name, using SPRING_DATASOURCE_URL, using the connection string as postgresql://[user]:[pass]#[service]/[database], I tried moving this line to the config-service instead since the database connection is indeed in the Spring Cloud Config Server microservice, but all to no avail. What's missing? It seems to be correct comparing to all the solutions I found.
I made Spring Config Server see my repository for the configurations. Thinking better, if it's reading from the repository it's evident that changing it on the fly locally won't work, so I updated the connection string of the configuration file for authorization-service then pushed, and it worked. I wonder if this is a good practice or better to make Config Server see local files and change it on the fly?
Hi i hope you are okay !
above your authorization-service add a link like this:
links:
- "postgres"
Greetings

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.

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

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.

Resources