I am running zuul in a docker container, but I cant connect to it via postman on my local host (windows 10) - spring-boot

I have 3 services
zuul, eureka, and a rest service.
Running the code locally via springboot works and I can use the url
http://localhost:8080/account/bank/account/
But when I dockerise it
The eurka application.yml
server:
port: '8761'
spring:
application:
name: eureka-service
eureka:
client:
fetchRegistry: 'false'
registerWithEureka: 'false'
Eureka local.dockerfile
FROM adoptopenjdk:16.0.1_9-jdk-hotspot-focal
EXPOSE 8761
RUN mkdir /app
COPY target/eureka-service.jar /app
WORKDIR /app
ENTRYPOINT ["java", "-jar", "/app/eureka-service.jar"]
The zuul application.yml
spring:
application:
name: zuul-service
server:
port: '8080'
eureka:
client:
instance:
preferIpAddress: 'true'
fetchRegistry: 'true'
registerWithEureka: 'true'
serviceUrl:
defaultZone: http://172.21.0.2:8761/eureka
zuul:
routes:
account:
path: /account/**
serviceId: account-service
zuul local.dockerfile
FROM adoptopenjdk:16.0.1_9-jdk-hotspot-focal
EXPOSE 8080
RUN mkdir /app
COPY target/zuul-service.war /app
WORKDIR /app
ENTRYPOINT ["java", "-jar", "/app/zuul-service.war"]
the rest application.yml
spring:
application:
name: account-service
server:
port: '8082'
eureka:
client:
instance:
preferIpAddress: 'true'
fetchRegistry: 'true'
registerWithEureka: 'true'
serviceUrl:
defaultZone: http://172.21.0.2:8761/eureka
rest local.dockerfile
FROM adoptopenjdk:16.0.1_9-jdk-hotspot-focal
EXPOSE 8082
RUN mkdir /app
COPY target/account-service.war /app
WORKDIR /app
ENTRYPOINT ["java", "-jar", "/app/account-service.war"]
I have two docker-compose files. Mainly through experimenting with trying to publish the ports.
Eureka and rest
version: "3"
services:
eureka-service:
image: eureka-service
container_name: eureka-service
build:
context: ../../eureka-service
dockerfile: local.dockerfile
ports:
- "8761:8761"
networks:
- banking-network
account-service:
image: account-service
container_name: account-service
build:
context: ../../account-service
dockerfile: local.dockerfile
ports:
- "8082:8082"
depends_on:
- eureka-service
environment:
- eureka.client.service-url.defaultZone=http://172.21.0.2:8761/eureka
networks:
- banking-network
networks:
banking-network:
external:
name: banking-network
zuul
version: "3"
services:
zuul-service:
image: zuul-service
container_name: zuul-service
build:
context: ../../zuul-service
dockerfile: local.dockerfile
ports:
- "8080:8080"
environment:
- eureka.client.service-url.defaultZone=http://172.21.0.2:8761/eureka
networks:
- banking-network
networks:
banking-network:
external:
name: banking-network
when I run docker-compose up on both docker-compose
zuul and application is registered with eureka
But in postman when I run http://localhost:8080/account/bank/account/
it fails.
If I am correct I need to publish zuul-service port to the host.
But this is where I am having real problems
So following the docker docs
I run the following on the zuul docker-compose
docker-compose run --publish 8080:8080 zuul-service
running docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea2957b56646 zuul-service "java -jar /app/zuul…" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp gateway_zuul-service_run_c3988736de38
Zuul and account are registered
But neither URLs work
http://localhost:8080/account/bank/account/
http://0.0.0.0:8080/account/bank/account/
I created a simple health page on zuul. to see if I can connect to zuul
This url works, when its run from springboot
http://localhost:8080/gateway/health/
But neither works from docker
http://localhost:8080/gateway/health/
http://0.0.0.0:8080/gateway/health/
I thought publishing 8080 to my local host, would mean I could use localhost

A few suggestions to debug the issue:
Put all services in one docker compose file and make sure they are on the same network
For defaultZone, change ip to eureka docker image name so instead of:
defaultZone: http://172.21.0.2:8761/eureka
Try:
defaultZone: http://eureka-service:8761/eureka/
I’d try without preferIpAddress: true If you don’t have multiple replicas of your registered services
After Exposing zuul gateway port, check what routes are available at localhost:8080/routes

The code does work. I found out that because I was developing my code in increments. I thought I was rebuilding a new image. I was not, I removed the images, rebuilt and the code works.

Related

Register Dockerized microservice to Eureka server - Springboot

In my production environment I have an Eureka Server running inside a docker container.
I can register to it other basic microservices with this kind of Application.yml
Application.yml:
server:
port: '8095'
spring:
application:
name: sap-listener
eureka:
instance:
preferIpAddress: true
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://172.17.0.2:8761/eureka
I create a DockerImage with this Dockerfile:
Dockerfile
FROM openjdk:17-jdk
ARG JAR_FILE=target/*.jar
COPY target/sap-listener-*.jar /sap-listener.jar
ENTRYPOINT ["java", "-jar", "/sap-listener.jar" ]
EXPOSE 8095
and then I run it in production with this command:
docker run -d -p 8095:8095 --name sap myrepo/sap-listener1.0:latest
The service is successfully registered to the Eureka server.
I came across to some problems when I try to run a bigger microservice which have a docker-compose file.
I send directly this docker-compose file in production:
Docker-compose
version: "3.3"
services:
docker-mysql:
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'password'
MYSQL_DATABASE: 'db'
ports:
- "3007:3306"
phpmyadmin:
image: phpmyadmin
restart: always
container_name: php-my-admin-users
ports:
- "8081:80"
ldap-app:
image: myRepo/service1:latest
ports:
- "8090:8090"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://docker-mysql:3306/db
depends_on:
- docker-mysql
And I run it with docker-compose -f docker-compose.yml up -d
service1 application.yml have the same type of connection with Eureka server of the previous microservice.
service1 is correctly deployed but It can't register himself to the Eureka server, if I log out the container output I have this error:
2022-06-29 15:45:20.551 INFO 1 --- [ main] c.n.d.s.t.d.RedirectingEurekaHttpClient : Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://172.17.0.2:8761/eureka/}, exception=I/O error on GET request for "http://172.17.0.2:8761/eureka/apps/": Connect to 172.17.0.2:8761 [/172.17.0.2] failed: Connection timed out; nested exception is org.apache.http.conn.ConnectTimeoutException: Connect to 172.17.0.2:8761 [/172.17.0.2] failed: Connection timed out stacktrace=org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://172.17.0.2:8761/eureka/apps/": Connect to 172.17.0.2:8761 [/172.17.0.2] failed: Connection timed out; nested exception is org.apache.http.conn.ConnectTimeoutException: Connect to 172.17.0.2:8761 [/172.17.0.2] failed: Connection timed out
I read that someone directly insert the Eureka Server data as a service inside the Docker-Compose.yml file, but my Eureka Server is already deployed and is already listening to a specific port.
That is probably happening because docker-compose automatically assign a network to the containers.
Try adding network_mode: host to your services in the compose file, like so:
version: "3.3"
services:
docker-mysql:
network_mode: host
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'password'
MYSQL_DATABASE: 'db'
ports:
- "3007:3306"
phpmyadmin:
network_mode: host
image: phpmyadmin
restart: always
container_name: php-my-admin-users
ports:
- "8081:80"
ldap-app:
network_mode: host
image: myRepo/service1:latest
ports:
- "8090:8090"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://docker-mysql:3306/db
depends_on:
- docker-mysql
First I would suggest you get familiar with how networking in Docker works and then have a look at networking in Docker-Compose.
When you run docker network ls when your containers are deployed you will see that they are running on different networks, which isolates them. Inspect the networks using docker network inspect <id> and you'll see they have different subnets. So for the services to be able to communicate they need to be on the same network.
You can manually create a network and use it in both compose and the docker cli.

Spring micro services eureka client is not registering with eureka server

I'm very new to everything about docker, spring framework... They run on localhost environment successfully, now I want to push them into docker, but always gave me error there, i got stuck on it about a week. Can someone help me figure it out PLEASE!!!
now I have eureka-server and cloud-config-server services, here is my code:
eureka-server application.yml
server:
port: 8761
spring:
application:
name: service-registration
eureka:
client:
register-with-eureka: false
fetch-registry: false
management:
security:
enabled: false
and Dockerfile:
FROM openjdk:11
COPY target/service-registration-0.0.1-SNAPSHOT.jar service-registration.jar
EXPOSE 8761
CMD ["java", "-jar", "service-registration.jar"]
Now I have cloud-config-server application.yml:
In this file, i tried to backup it on github.
From the start, I tried to change the hostname as localhost or any other hostname like service-registration, eureka-server etc... but not work, and "service-url" or "serviceUrl'....
server:
port: 9291
spring:
application:
name: cloud-config-server
profiles:
active: production
# cloud:
# config:
# server:
# git:
# uri: https://github.com/sshaunn/config-server
# clone-on-start: true
eureka:
client:
register-with-eureka: true
fetch-registry: true
serviceUrl:
defaultZone: http://service-registration:8761/eureka/
instance:
# prefer-ip-address: true
# ip-address: http://eureka-server:8761/eureka/å
hostname: service-registration
Dockerfile:
FROM openjdk:11
COPY target/cloud-config-server-0.0.1-SNAPSHOT.jar cloud-config-server.jar
EXPOSE 9291
ENTRYPOINT ["java", "-jar", "cloud-config-server.jar"]
and the docker-compose.yml file:
version: '3.7'
services:
service-registration:
image: service-registration
networks:
- eureka-server
ports:
- "8761:8761"
container_name: service-registration
hostname: service-registration
cloud-config-server:
build: cloud-config-server
networks:
- eureka-server
ports:
- "9291:9291"
depends_on:
- service-registration
container_name: cloud-config-server
hostname: service-registration
environment:
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://service-registration:8761/eureka
networks:
eureka-server:
name: eureka-server
driver: bridge
# route:
# image: route
# ports:
# - "9191:9191"
# container_name: api-gateway
# environment:
# EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://service-registration:8761/eureka
The error logs here:
2022-05-29 07:22:41.713 WARN 1 --- [freshExecutor-0] c.n.d.s.t.d.RetryableEurekaHttpClient : Request execution failed with message: I/O error on GET request for "http://localhost:8761/eureka/apps/": Connect to localhost:8761 [localhost/127.0.0.1] failed: Connection refused (Connection refused);
2022-05-29 07:06:11.565 WARN 1 --- [tbeatExecutor-0] c.n.d.s.t.d.RetryableEurekaHttpClient : Request execution failed with message: I/O error on PUT request for "http://localhost:8761/eureka/apps/CONFIG-SERVER/service-registration:CONFIG-SERVER:9291": Connect to localhost:8761 [localhost/127.0.0.1] failed: Connection refused (Connection refused);
Ok, I dont know why but I set up a docker-compose.yml file like this and it works:
Note, I set up environment about "service-url" defaultZone in docker-compose.yml file.
version: '3.7'
services:
service-registration:
container_name: service-registration
build:
context: ./service-registration
dockerfile: Dockerfile
ports:
- "8761:8761"
cloud-config-server:
container_name: cloud-config-server
build:
context: ./cloud-config-server
dockerfile: Dockerfile
environment:
- eureka.client.service-url.defaultZone=http://service-registration:8761/eureka
depends_on:
- service-registration
ports:
- "9191:9191"
route:
container_name: route
build:
context: ./route
dockerfile: Dockerfile
environment:
- eureka.client.service-url.defaultZone=http://service-registration:8761/eureka
depends_on:
- service-registration
- employee
- income
ports:
- "9291:9291"
employee:
container_name: employee
build:
context: ./employee
dockerfile: Dockerfile
environment:
- eureka.client.service-url.defaultZone=http://service-registration:8761/eureka
depends_on:
- service-registration
ports:
- "9001:9001"
income:
container_name: income
build:
context: ./income
dockerfile: Dockerfile
environment:
- eureka.client.service-url.defaultZone=http://service-registration:8761/eureka
depends_on:
- service-registration
ports:
- "9002:9002"
You should use your host ip address to run in your local machine. For the docker it should not be localhost
Try with the below configuration in your application.properties file.
eureka.client.service-url.defaultZone=http://host.docker.internal:8761/eureka/

Api Gateway adding "localhost" to address on docker-compose

I'm trying to deploy SpringBoot microservices using docker-compose but I'm having a problem with API Gateway.
If I run the project locally it works ok, even if I deploy project using docker-compose but API Gateway locally, it works ok, so problem has to be "dockerizing" the API Gateway service.
Doing docker logs <container> it shows:
io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: localhost/127.0.0.1:8083
Is obvious there is a problem on host localhost/127.0.0.1. Why Gateway is trying to point a "repeated" address?.
docker-compose.yml looks like this:
version: '3.8'
services:
# more services
api-gateway:
build: ./path_to_dockerfile
depends_on:
- eureka-server
environment:
- eureka.client.serviceUrl.defaultZone=http://eureka-server:8761/eureka/
restart: always
container_name: gateway
ports:
- '9000:9000'
Dockerfile is as simple as this
FROM openjdk:8-jdk-alpine
ADD target/apigateway-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
And application.yml:
server:
port: 9000
spring:
application:
name: Api-Gateway-Service
cloud:
gateway:
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE
globalcors:
# cors config
routes:
- id: <name>-microservice
uri: http://localhost:8083
predicates:
- Path=/<path>/**
- Method=GET,POST,DELETE,PUT,OPTIONS
# more routes on different ports
eureka:
# eureka config
So, why is adding "localhost" or "127.0.0.1" and calling twice?
Thanks in advance.
I don't think Connection refused: localhost/127.0.0.1:8083 means that it was trying to add or call localhost twice. It is just the way it shows the error.
In your application.yml, try changing uri to the name you used for your microservice inside docker-compose file.
routes:
- id: <name>-microservice
uri: <YOUR_SERVICE_NAME>
I guess the problem is that docker doesn't support network communication between containers by default. You can connect to the 8083 port from your host but not another container. If so, you should create a network and contact the container and network.

Dockerizing SpringBoot Mongo Exception opening socket

I am trying to dockerize my spring boot and mongo.
This is my application.yml
spring:
application:
name: service-app
data:
mongodb:
uri: mongodb://localhost:27017/user
I have found this to be recommended in other posts.
The error I get is:
Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~.
[mongodb-driver-core-4.1.1.jar:na]
version: '3'
services:
mongo:
image: library/mongo:latest
container_name: mongo
restart: always
ports:
- 27017:27017
network_mode: host
volumes:
- $HOME/mongo:/data/db
healthcheck:
test: "exit 0"
user-service:
build:
context: .
dockerfile: Dockerfile
image: user-service
depends_on:
- mongo
network_mode: "host"
hostname: localhost
restart: always
ports:
- 8082:8082
healthcheck:
test: "exit 0"
FROM openjdk:8-jdk-alpine
ADD ./target/demo-0.0.1-SNAPSHOT.jar /usr/src/user-service-0.0.1-SNAPSHOT.jar
WORKDIR usr/src
ENTRYPOINT ["java -Djdk.tls.client.protocols=TLSv1.2","-jar", "user-service-0.0.1-SNAPSHOT.jar"]
It seems to be a common problem for noobsters, I couldn't solve it with what was on the internet already.
The problem is in not building the url properly.
By the information I gave, I should have gotten a proper answer, instead I got -1.
Some people are true trolls with privileges.
uri: mongodb://mongo/user
I feel like it became a gamble on Stackoverflow, depends on the type of people crossing over your question.

Access to local database denied through docker container

I am having a problem connecting my compiled Spring-Boot app to the database that I have running on another container on my server.
I have tried different configurations, changing from localhost to the IP address of my server for the connection. I also double checked that the credentials matched by logging in via Adminer. Finally, I did a rebuild of the compose and image files several times to ensure that I have all the latest versions.
Compose file:
version: '3.1'
services:
db:
image: mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: mypassword
MYSQL_DATABASE: marketingappdb
ports:
- "3306:3306"
expose:
- 3306
volumes:
- ./mariadbvolume:/var/lib/mariadb
networks:
- marketingapp
adminer:
image: adminer
restart: always
ports:
- "8086:8080"
expose:
- 8086
depends_on:
- db
networks:
- marketingapp
springserver:
image: marketingapp
restart: always
ports:
- "8091:8091"
expose:
- 8091
depends_on:
- db
networks:
- marketingapp
networks:
marketingapp:
Spring Server Image:
FROM openjdk:latest
COPY /marketing-app-final.jar .
EXPOSE 8091
ENTRYPOINT ["java", "-jar", "marketing-app-final.jar"]
Application properties for Spring:
server.port = 8091
spring.datasource.url=jdbc:mariadb://0.0.0.0:3306/marketingappdb
spring.datasource.username=root
spring.datasource.password=mypassword
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
I can connect from my PC to the database using the app from the remote same configuration (obviously replacing localhost with the IP) and don't see why I shouldn't be able to do the same from the actual server. Thanks in advance for any help!
Use the docker dns to connect your spring App to the mariabd:
jdbc:mariadb://db:3306/marketingappdb
Just a few other hints: you don't need to expose port 3306, you already bind it to 3306 on Host (if you just want to use it from within the docker Services you don't need to bind/expose it at all). And the mariabd persistent storage is var/lib/mysql and not var/lib/mariadb

Resources