How to connect Spring Boot application to a Postgres database that's in a Docker container - spring

I'm working on a Spring Boot application and it has to use a database. I can run the database locally and connect to it without problems but now I'm trying to run just the database in a Docker container and connect to it with my Spring application and I can't get it to work.
This is the docker-compose file that is used to start the docker container with the postgres image
version: '3.8'
services:
db:
container_name: postgres-container
image: postgres:14.1-alpine
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=shop
ports:
- '5432:5432'
volumes:
- db:/var/lib/postgresql/data
volumes:
db:
driver: local
This is the application.yml file
spring:
datasource:
url: jdbc:postgresql://localhost:5432/shop
username: postgres
password: password
This is the V1.0__init.sql file used to initiate a table in the database
CREATE TABLE IF NOT EXISTS igredient(
id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(50) NOT NULL,
price INTEGER NOT NULL,
is_healthy BOOL NOT NULL,
type VARCHAR(10)
);
I tried connecting to the database with DBeaver in the following way (can't upload an image):
Host: localhost
Port: 5432
Database: shop
Authentication: Database Native
Username: postgres
Password: password
Advanced:
Local Client: PostgreSQL 14
When I test the connection I get this "FATAL: database "shop" does not exist" and I don't understand what I'm missing. I have been googling for too long and I don't have a clue what else to do.
I tried running the Spring application but I get this error:
org.postgresql.util.PSQLException: FATAL: database "shop" does not exist
and this:
Message : FATAL: database "shop" does not exist
Also DB Browser in Intellij is giving me this error in the V1.0__init.sql file (I guess because I'm not connected to a database):
Invalid or incomplete statement
expected one of the following:
BITMAP CONTEXT DIRECTORY EDITIONABLE EDITIONING FORCE FUNCTION INDEX MATERIALIZED MULTIVALUE NO NONEDITIONABLE OR PACKAGE PROCEDURE PUBLIC ROLE SEQUENCE SYNONYM TRIGGER TYPE UNIQUE USER VIEW

Related

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

Connection Refused : While Running the Docker Compose

I am new baby to the Docker. I am using docker within the spring boot application. Below is my file .
Application.properties file:
spring.datasource.url=jdbc:mysql://${DATABASE_HOST}:3306/${DATABASE_NAME}?allowPublicKeyRetrieval=true&useSSL=true
spring.datasource.username = root
spring.datasource.password = root
server.port=8443
DockerFile:
FROM openjdk:latest
ADD target/app.jar app.jar
EXPOSE 8443
ENTRYPOINT ["java","-jar","app.jar", "--spring.profiles.active=docker"]
Docker Compose :
version: '3.1'
services:
mysqlDb:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=springdemo
- MYSQL_USER=root
- MYSQL_PASSWORD=root
- DATABASE_HOST= 192.168.0.1
volumes:
- /data/mysql
ports:
- "3306:3306"
container_name: mysql-db
springbootdocker:
image: xyz/signup
restart: always
ports:
- "8080:8080"
depends_on:
- mysqlDb
links:
- mysqlDb
environment:
- DATABASE_HOST= mysqlDb
- DATABASE_USER=root
- DATABASE_PASSWORD=root
- DATABASE_NAME=springdemo
- DATABASE_PORT=3306
healthcheck:
test: ["CMD","curl","-f","http://localhost:8080/health"]
interval: 1m30s
timeout: 10s
retries: 3
1st part of Issue is Resolved :
when i run the App , i get the following error :
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.UnknownHostException: ${DATABASE_HOST}
1) What i am trying to Achieve -
Want to create a jar for my application.
After creating a jar , i want to create the image from the jar
After creating the image of the application , i want to push into the docker hub .
From other server , I will run docker-compose.yml file . It will fetch the mysql and image from the docker hub and run the application in the other port as mentioned in the docker-compose.
Hope I am clear ,what i want to acheive .
Here comes the problem :
when i am trying to run the application locally , i am able to create the jar only when ,i write this line in application.properties class.
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springdemo?allowPublicKeyRetrieval=true&useSSL=true
I am able to create the jar and after that image to -> upload that image to docker hub , when i am running the docker-compose able to pull that image but can't able to connect to the mysql workbench.
So,I thought, I am running the docker-compose in diffrent System/Server. There ip address is different.
So, I changed the url to this :
spring.datasource.url=jdbc:mysql://192.168.0.1:3306/springdemo?allowPublicKeyRetrieval=true&useSSL=true
where
192.168.0.1 - this ip is for the diffrent server, where i want to run the docker-compose file
But when i am running the spring boot application , I am unable to run the application because it's saying the almost the same error as mentioned above i.e Connection refuse . So i am unable to create the jar so , unable to create the image . So my idea fails here also.
Then Again, One idea again come into my mind , can't we put the dynamic ip address in application.properties file,so i tried this line :
spring.datasource.url=jdbc:mysql://${DATABASE_HOST}:3306/${DATABASE_NAME}?allowPublicKeyRetrieval=true&useSSL=true
DATABASE_HOST- you can find it in docker-compose file
I thought may be this one : ${DATABASE_HOST} , will pick the value of the DATABASE_HOST from the docker-compose .
But my idea failed , I am getting the error as mentioned in top while running the application. can't able to create jar ,so unable to create the image .
2nd Part - Issue is still Open
when i am able to run the docker-compose in my local terminal , and able to create the container . I can also see mysql is connected as well as my schema .
But when i am trying to access my API using postman or web browser then , it's saying not connected
http://localhost:8080/dockerex
Inside my Controller Class:
#RestController
#RequestMapping(value = "/dockerex")
public class SpringBootDockerController {
#GetMapping
public String check() {
return "checking";
}
}
when i inspect my container , ip address is coming blank : snapshot of conatiner :
[
{
"Id": "7664bab5ed452e3e2243e1802010240ab5a3eb817af6164e985b10e729ff4c8f",
"Created": "2020-02-04T17:30:08.5351511Z",
"Path": "java",
"Args": [
"-jar",
"app.jar",
"--spring.profiles.active=docker"
],
"State": {
"Status": "running"
.......................
"PortBindings": {
"8080/tcp": [
{
"HostIp": "",
"HostPort": "8080"
}
]
},
Good it worked but here you see you were using DB_HOST earlier, now you are using DATABASE_HOST= mysqlDb , which is currently pointing to your mysql service name.
this service name can be discovered within the single network created by docker compose.
You were hardcoding DB_HOST=192.168.0.1 and trying to connect using this IP , which is invalid as docker compose create its network.
You have to mention service name here as in your case db service name is mysqlDb. Below is the updated application.properties
spring.datasource.url=jdbc:mysql://$(DB_HOST:mysqlDb):3306/springdemo?allowPublicKeyRetrieval=true&useSSL=true
spring.datasource.username = root
spring.datasource.password = root
server.port=8443
Try this:
Replace DB_HOST= 192.168.0.7 to DB_HOST= mysqldb in your docker-compose file.
And update your application.properties file:
spring.datasource.url=jdbc:mysql://$(DB_HOST:mysqlDb):3306/springdemo?allowPublicKeyRetrieval=true&useSSL=true
to this:
spring.datasource.url=jdbc:mysql://$(mysqlDb):3306/springdemo?allowPublicKeyRetrieval=true&useSSL=true
Thanks everyone : I got the solution by hit and trail :P
spring.datasource.url=jdbc:mysql://${DATABASE_HOST:localhost}:${DATABASE_PORT:3306}/springdemo?allowPublicKeyRetrieval=true&useSSL=true

volume in oracle database not saving user information

I create a local oracle database but my volume is not saving my user. I do the following.
1) docker login
2) docker-compose up
3) docker exec -it <container id> bin/bash
4) sqlplus / as sysdba
5) alter session set "_ORACLE_SCRIPT"=true;
6) create user admin identified by admin;
7) GRANT CREATE SESSION, CREATE DATABASE LINK, CREATE MATERIALIZED VIEW,
CREATE PROCEDURE, CREATE PUBLIC SYNONYM, CREATE ROLE,CREATE SEQUENCE,
CREATE SYNONYM, CREATE TABLE,
CREATE TRIGGER, CREATE TYPE, CREATE VIEW, UNLIMITED TABLESPACE to admin;
docker-compose.yml
version: "3"
services:
database:
image: "store/oracle/database-enterprise:12.2.0.1-slim"
ports:
- "1521:1521"
environment:
- DB_SID=XE
- DB_PASSWD=admin
volumes:
- oracle-database:/opt/oracle/oradata
volumes:
oracle-database:
However when I run docker-compose down and then up I have to respeat all the step again confirming the volume is not working. Has someone ran into this issue before?

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.

Connect from web app to Oracle DB docker container

I'm running on the same host a tomcat container where I've deployed a web application and an oracle DB container. The settings I'm using the following settings to connect from the web app to the oracle DB container:
spring.datasource.url: jdbc:oracle:thin:#<IP of the host>:1521:xe
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=com.mysql.jdbc.Driver
As I'm exposing the port 1521 to the host, I was expecting to be able to connect to the Oracle DB with no issues, furthermore, I can connect from my laptop to the Oracle DB using DbVisualizer using the settings described above. I've also got into the tomcat container and pinged the host with success.
I know I could link both containers when running the "docker run" command but I was wondering if it could work this way too.
Any ideas? Thanks!
A simple way to do this is using docker-compose:
docker-compose.yml
version:'3'
services:
app:
// if you got a custom dockerfile
build: .
links:
- db
db:
image: oracledb
The db host into app will "db":
spring.datasource.url: jdbc:oracle:thin:db:1521:xe
To run bought contanier at the same time is: docker-compose up --build
I hope you find it useful.

Resources