Connect from web app to Oracle DB docker container - spring

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.

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)

Unable to connect from Spring Boot to Dockerized Redis in outside/inside machine

I am connecting to Redis from the spring boot app on the outside machine where the Redis server docker container is not running. When the app tries to connect to Redis, the app can't connect properly until the sent request is timed out. Meanwhile, if I try to connect from:
Inside the machine where the Redis server docker container is running with the host is localhost, I could connect it. And, I don't know why I can't connect by setup host value as a numerical IP/alphabetical (URL), only works with "localhost."
Outside machine where the Redis server docker container is not running with Redis client app GUI for management, I could connect it.
application.properties:
spring.redis.host=pc-1
spring.redis.port=6379
pc-1 is alias from some numerical ip. I'am using hosts feature from
windows to aliasing/redirecting it.
.env:
REDIS_PORT=6379
docker-compose.yml:
redis:
image: redis:latest
ports:
- "${REDIS_PORT}:6379"
command:
# - redis-server
# - --requirepass "${REDIS_PASSWORD}"
networks:
- redis
healthcheck:
test: ["CMD-SHELL", "redis-cli ping"]
interval: 10s
timeout: 10s
retries: 3
I need help on this issue.
Use the --service-ports flag to the docker compose command to publish the ports you've defined in the docker compose file.
Other debugging tips:
Hardcode the ${REDIS_PORT} variable in case the value is not getting set or set a default like ${REDIS_PORT:-default}
Pass the env file explicitly like docker compose --env-file ./somedir/.env up in case the env file is not being pick up
Use docker inspect to get container status, check the networking info

How to connect my spring boot app to redis container on docker?

I have created a spring app and i want to connect it to redis server which is deployed on docker-compose i put the needed properties as follow :
spring.redis.host=redis
spring.redis.port=6379
But i keep getting a ConnexionException so how can i Know on which host redis is running and how to connect to it.
Here is my docker-compose file :
version: '2'
services:
redis:
image: 'bitnami/redis:5.0'
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
ports:
- '6379:6379'
volumes:
- 'redis_data:/bitnami/redis/data'
volumes:
redis_data:
driver: local
From docker compose documentation
By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name
If you want to access redis by container name ('redis' in this case), the Spring boot application has also be deployed as a docker compose service, but it doesn't appear in the docker-compose file that you've provided in the question, so please add it.
Alternatively If you're trying to run the spring boot application on host machine, use 'localhost' instead of 'redis' in order to access the redis container.
Another approach you can use is "docker network" , Below are the steps to follow :
Create a docker network for redis
docker network create redis-docker
Spin up redis container is redis-docker network.
docker run -d --net redis-docker --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
Inspect the redis-docker container
docker network inspect redis-docker
Copy the "IPv4Address" IP and paster in application.yml
Now build , start your application.

Dockerized Spring boot app connect to database docker image

I have a basic spring boot application with gradle which makes calls to an Oracle database and the database properties are specified in an application.properties file.
I created a Docker image of the spring boot application with the plugin "com.google.cloud.tools.jib" and using the following command:
./gradlew jibDockerBuild --image=app1
I have a docker-compose file in which i specify the image as an service and i want the application to start when i run the command: "docker-compose up"
The docker-compose file is the following:
version: '3'
services:
app1:
image: "app1"
ports:
- "8731:8731"
But when I hit the run the "docker-compose up" command in CMD I recieve the following exception:
java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection
More informations:
My Oracle database is a docker container with the name : "ORA12201_1" and port 3769
Inside the application.properties the database properties specified are correct since I am amble to start the application from IntelliJ
you can connect from IntelliJ without problem as the container exposes the port (3769) to the host (your PC), but now you are trying to connect from one Docker container to another.
The containers do not share the network (isolation) so you need to connect them.
One of the recommended approach is User-defined networks
Create first a network
docker network create --driver bridge my_network
Run the applications
docker run -p 5432:5432 --network my_network -d --name=postgres postgres
docker run -p 5050:80 --network my_network -d --name=pgadmin dpage/pgadmin4
You can verify they are effectively running on the same network with
docker network inspect my_network
Spring Boot config
You can now connect from one to another using host.docker.internal as hostname, for example in your Spring Boot application.properties
spring.datasource.url=jdbc:postgresql://host.docker.internal:5432/postgres

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.

Resources