Connecting spring boot docker container to MQTT docker container - java

I'm trying to connect my containerized spring boot application with another containerized MQTT broker. Both of them are on their own projects as follows:
mqtt docker-compose.yml:
version: '3.9'
services:
mqttbroker:
container_name: mqttbroker
restart: always
volumes:
- ./config:/mosquitto/config
- ./data:/mosquitto/data
- ./log:/mosquitto/log
ports:
- 8883:8883
networks:
- mynetwork
volumes:
config:
data:
log:
mqtt Dockerfile
FROM eclipse-mosquitto
WORKDIR /mosquitto
COPY . .
EXPOSE 8883
And then the spring boot project is like:
spring boot docker-compose.yml
version: '3.8'
services:
myapp:
build: .
container_name: myapp
ports:
- '8082:8082'
stdin_open: true
tty: true
networks:
- mynetwork
In my application.properties I try to connect to the MQTT broker like:
mosquitto.url=tcp://mqttbroker:8883 and I get connection refused. However, if I run the spring boot application locally, I can connect to the docker container with mosquitto.url=tcp://localhost:8883.
I would rather have all the configurations in my docker-compose files to decrease manual codes.
I really appreciate your help in advance!

Yes, You do have to share the network as external.
you cab check the networks you have with this command : docker network ls
You would notice that they each have their own networks.
adding this to spring boot docker-compose file should fix the issue :
networks:
default:
name: mynetwork
external: true
For more information about docker compose networks

Related

Docker Compose connect to external Postgres databases

I have a SpringBoot application that works perfectly. Now I am trying to Dockerise it, but have some issues when connecting to the database.
The application has two datasources:
application.properties
server.port= 8081
# pims datasource
spring.datasource1.driver-class-name=org.postgresql.Driver
spring.datasource1.jdbc-url=jdbc:postgresql://localhost:5432/pims
spring.datasource1.username=postgres
spring.datasource1.password=
spring.jpa.database-platform=postgres
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=false
# approval datasource
spring.datasource2.driver-class-name=org.postgresql.Driver
spring.datasource2.jdbc-url=jdbc:postgresql://localhost:5432/approval
spring.datasource2.username=postgres
spring.datasource2.password=
In the application, I use Spring to access the two datasources:
#Configuration
#ComponentScan(basePackages = "com.nexct")
public class MultipleDBConfig {
#Bean(name = "datasource1")
#ConfigurationProperties("spring.datasource1")
#Primary
public DataSource dataSource1(){
return DataSourceBuilder.create().build();
}
#Bean(name = "datasource2")
#ConfigurationProperties("spring.datasource2")
public DataSource dataSource2(){
return DataSourceBuilder.create().build();
}
}
So I have created:
Dockerfile
FROM openjdk:14
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} nexct-approval-service.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","/nexct-approval-service.jar"]
docker-compose.yml
version: '3.7'
services:
product-service:
build: ../nexct-approval-service
volumes:
- ../nexct-approval-service:/usr/src/app
ports:
- "8081:8081"
db:
image: postgres
environment:
POSTGRES_DB_PORT: "5432"
POSTGRES_DB_HOST: "localhost"
POSTGRES_PASSWORD:
POSTGRES_USER: postgres
POSTGRES_DB: pims
However, I am not sure how to configure the two Postgres databases.
Any advise would be appreciated.
Note: the databases are not running in a container, as they are used by other legacy applications.
If I remove the db from docker-compose.yml. When I run docker-compose up, the Spring Boot application starts, and I can access a RESTful service. However, I get the following error:
PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
version: '3.7'
services:
product-service:
build: ../nexct-approval-service
volumes:
- ../nexct-approval-service:/usr/src/app
ports:
- "8081:8081"
server.port=8081
# pims datasource
spring.datasource1.driver-class-name=org.postgresql.Driver
spring.datasource1.jdbc-url=jdbc:postgresql://<postgres_host_private_ip>:5432/pims
spring.datasource1.username=postgres
spring.datasource1.password=
spring.jpa.database-platform=postgres
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=false
# approval datasource
spring.datasource2.driver-class-name=org.postgresql.Driver
spring.datasource2.jdbc-url=jdbc:postgresql://<postgres_host_private_ip>:5432/approval
spring.datasource2.username=postgres
spring.datasource2.password=
Replace <postgres_host_private_ip> with the private IP of the machine hosting the postgres databases.
I'm not sure what you were trying to achieve with the nested db service, but since your database are already running somewhere outside there is no need for this.
Your Spring application will run on a isolated network from your host because of the docker isolation (unless explicitly asked to use host network with network_mode: "host"). Knowing that, the "localhost" can not work inside the container, you need to use the real IP of the machine that hosts the databases. Most likely something like 192.168.xxx.xxx
Also, you need to make sure the postgres is configured to accept connection from "non-localhost" sources (see https://www.andrew-kirkpatrick.com/2017/05/allow-connection-postgresql-server-outside-localhost/).
To access an application running on ur Host there are few options
Use the Bridge network. (Doc)
Create a bridge network and assign the subnet address and gateway address.
Now you can reach your application running at the host from the container at <gateway address>:<port> i.e 172.28.0.1:<port>
version: '3.7'
services:
product-service:
build: ../nexct-approval-service
volumes:
- ../nexct-approval-service:/usr/src/app
ports:
- "8081:8081"
networks:
hostnet: {}
networks:
hostnet:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
Use Attach service to host network. (Doc)
add network_mode: host to your service (only works on Linux)
OR create an external network
Now you can reach your application running at the host from the container at localhost:<port>
With network_mode: (Linux)
version: '3.7'
services:
product-service:
build: ../nexct-approval-service
volumes:
- ../nexct-approval-service:/usr/src/app
ports:
- "8081:8081"
network_mode: host
Try configuring your docker-compose file to use bridged networking:
version: '3.7'
services:
product-service:
build: ../nexct-approval-service
volumes:
- ../nexct-approval-service:/usr/src/app
environment:
POSTGRES_DB_PORT: "5432"
POSTGRES_DB_HOST: "localhost"
POSTGRES_PASSWORD:
POSTGRES_USER: postgres
POSTGRES_DB: pims
networks:
- product_service_network
networks:
product_service_network:
driver: bridge
You also have to move the ENVIRONMENT variables to product-service if you are going to use them in the product-service container.
If localhost doesn't work, use 127.0.0.1 instead.

503 error code for Springboot container connecting to mongo container using docker-compose

I am trying to connect my spring-boot application(REST endpoints) running in a Tomcat container with a mongo container. I am using docker-compose to link both the containers. The application was working perfectly fine. It just stopped working suddenly.
Following is my code:
Dockerfile:
FROM tomcat:9.0.13
WORKDIR /usr/local/tomcat/webapps
#COPY pom.xml .
#RUN ["mvn", "clean", "install"]
COPY /target/TestProfileManager.war .
docker-compose.yml:
version: '3'
services:
app:
container_name: VF-BACKEND
restart: always
build: .
ports:
- "8083:8080" #VF Webservice
depends_on:
- mongo
links:
- mongo
mongo:
container_name: VF-MONGO
image: mongo:4.0.2
ports:
- "27018:27017"
volumes:
- /data/vfdb:/data/db
application.properties
spring.data.mongodb.uri=mongodb://mongo:27018/tsp
If I run the application from the IDE as a standalone application, the endpoints do return the response. Only during container communication, I am getting 503. I could not find any post that answers my question.
Thanks for the help. Since, the code was working before, not pasting the classes. Let me know if I should share them as well.
It should be mongodb://mongo:27017, in service to service communication you do not need to use publish port.
It is important to note the distinction between HOST_PORT and
CONTAINER_PORT. the HOST_PORT is 27018 and the container port is
27017 . Networked service-to-service communication use the
CONTAINER_PORT
compose-networking

Unable to connect to mysql in docker container from another docker container

I have two docker containers: mysql and spring boot service.
Service container is not connecting to mysql container(failing on the deploy) with following exception:
CommunicationsException: Communications link failure
So far I have tried using docker --link, docker networks, running everything using/without docker compose.
I am able to connect to DB container outside of docker.
Connection string: jdbc:mysql://db:3306/somedb
docker-compose.yml
version: '3.7'
services:
app:
build: .
restart: unless-stopped
ports:
- "80:8060"
links:
- db
depends_on:
- db
db:
image: "mysql:latest"
command: --default-authentication-plugin=mysql_native_password
environment:
- MYSQL_DATABASE=somedb
- MYSQL_ROOT_PASSWORD=somepassword
ports:
- "3306:3306"
volumes:
- /Users/someuser/someproject/mysql/data:/var/lib/mysql
I had the same problem earlier and i tried with by changing the mysql image version. Here is my compose yaml file where i am able to connect it with.
version: "3.0"
services:
spring-boot-container:
build: .
ports:
- "8086:8086"
links:
- mysql-standalone
mysql-standalone:
image: mysql:5.6
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: springsecurity
MYSQL_USER: sa
MYSQL_PASSWORD: password
So in my service dockerfile I say:
ADD target/app-1.0-SNAPSHOT.jar /app-service.jar
RUN sh -c 'touch /app-service.jar'
But I forgot to rebuild jar after making changes in service config files
TL;DR I'm retarded

How to make Spring boot with Redis Sentinel work with Docker

I am trying to set up a Spring boot application with Redis Sentinel 3.2.11 using docker. However I am getting
Caused by: io.netty.channel.ConnectTimeoutException: connection timed out: /172.27.0.2:6379
My docker compose configuration
version: '3.1'
services:
master:
image: redis:3
container_name: redis-master
hostname: host_dev
networks:
- docker_dev
slave:
image: redis:3
command: redis-server --slaveof redis-master 6379
hostname: host_dev
links:
- master:redis-master
container_name: redis-slave
networks:
- docker_dev
sentinel:
build: sentinel
environment:
- SENTINEL_DOWN_AFTER=5000
- SENTINEL_FAILOVER=5000
- MASTER_NAME=mymaster
hostname: host_dev
image: sentinel:3
links:
- master:redis-master
- slave
container_name: sentinel
ports:
- "26379:26379"
networks:
- docker_dev
networks:
docker_dev:
Docker file
FROM redis:3
EXPOSE 26379
ADD sentinel.conf /etc/redis/sentinel.conf
RUN chown redis:redis /etc/redis/sentinel.conf
ENV SENTINEL_QUORUM 2
ENV SENTINEL_DOWN_AFTER 30000
ENV SENTINEL_FAILOVER 180000
COPY sentinel-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/sentinel-entrypoint.sh
ENTRYPOINT ["sentinel-entrypoint.sh"]
Spring configuration in application.properties:
redis.cluster.name=mymaster
redis.sentinel.nodes=localhost:26379
redis.timeout=2000
Issue:
The spring boot app(run from outside docker-machine) is able to connect with Sentinel node. The sentinel node provides the master information with IP 172.27.0.2 i.e docker n/w IP. The spring boot app tries to connect with redis-master at IP 172.27.0.2 and fails as the IP is not visible outside the docker machine.
Possible fix:
How can I make sentinel node provide an master IP as localhost instead of internal docker-machine n/w ip?

Issue linking containers in Docker using Docker-compose

I'm using Docker to get my micro services architecture ready.
I'm facing some problem trying to link one container with another using docker-compose.
Basically I have a container for a postgressql image, and the a java micro service developed with spring boot that should connect to the database container.
So I'm setting a link in docker-compose.yml and referencing the db container ip as 'db' using :
- "JAVA_OPTS=-Dpostgres.host=db"
However I'm getting the following error starting the microservice with docker:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'postgress.host' in value "jdbc:postgresql://${postgress.host}:5432/docker"
So basically this placeholder cannot be resolved, but normally docker-composed should take care of setting this system variable to point to the db container IP address right?
What I'm doing wrong?
Below the files involved:
docker-compose.yml:
version: "2"
services:
microservices:
build: ./microservices
container_name: microservices
links:
- db
- consul
environment:
- "JAVA_OPTS=-Dpostgres.host=db"
consul:
image: consul
container_name: consul
ports:
- "8500:8500"
db:
image: postgres
container_name: local-postgres9.6
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: docker
POSTGRES_USER: docker
application.yml of the microservice:
server:
port: 8081
project:
jdbc:
url: jdbc:postgresql://${postgres.host}:5432/docker
driver: org.postgresql.Driver
username: docker
password: docker
Try ${db.host}, according to the documentation:
Containers for the linked service will be reachable at a hostname
identical to the alias, or the service name if no alias was specified.

Categories