Springboot WebClient Broken in docker container - spring-boot

Iv created two Springboot applications that Iv dockerized and created local containers.
When I run the applications locally through intellij on my machine they work ok. Application A, on localhost:8080 has a Spring WebClient with a baseUrl localhost:8081 configured to call Application B running on port 8081. This works great.
The problem starts when I add those container to a docker compose file and spin then up
version: "3.7"
services:
appa:
image: application/myapp:1
hostname: localhost
ports:
- 8080:8080
appb:
image: application/myapp:2
hostname: localhost
ports:
- 8081:8081
I can hit localhost:8080 from the browser, but when the client in the application tried to call application b using the WebClient, it falls over with
Error has been observed at the following site(s):
| |_ checkpoint ⇢ Request to GET
http://localhost:8081/api/feed [DefaultWebClient]
| Stack trace:
| Caused by: java.net.ConnectException: finishConnect(..) failed:
Connection refused
I can hit both apps from the browser or curl, but it seems they cant communicate internally inside the docker containers
Any help appreciated

If you are using localhost inside one container to try to communicate with a service running inside another container, that's the wrong host to use. localhost inside a container refers to the container itself not its host. To establish a connection between containers, you'll need to use the IP address of the container that you want to connect to rather than localhost. This networking tutorial may be of interest.

Related

Cannot reach Jolokia JVM agent

I'm trying to connect my Jolokia JVM agent with an hawtio frontend.
The agent runs inside of a docker container with the distroless java 11 image.
I start the application like this:
ENTRYPOINT ["java","-javaagent:jolokia-agent.jar","-jar","service1.jar"]
The Jolokia version is 1.6.2.
When I start up the application, this appears first.
| I> No access restrictor found, access to any MBean is allowed
| Jolokia: Agent started with URL http://127.0.0.1:8778/jolokia/
In my docker-compose.override file, I forward the port:
services:
service1:
ports:
- "8778:8778"
However, when I try to access the endpoint from the browser, it cannot reach it.
When I try curl curl "http://localhost:8778/jolokia from inside the container, I also cannot reach it.

Unable to connect to redis sentinel running on docker in my local Spring boot

I'm using Spring boot 2.2.5 and Spring data redis and bitnami/redis-sentinel
sentinel docker image.
bitnami/redis-sentinel docker image works fine with docker compose.
I can connect to the redis with redis-cli. (cli shows 127.0.0.1:6379 connected)
But in my local Spring boot application, it doesn't work.
Error trace is like:
org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 172.28.0.2:6379
at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:109) ~[spring-data-redis-2.2.5.RELEASE.jar:2.2.5.RELEASE]
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 172.28.0.2:6379
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78) ~[lettuce-core-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Caused by: io.netty.channel.ConnectTimeoutException: connection timed out: /172.28.0.2:6379
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe$1.run(AbstractNioChannel.java:261) ~[netty-transport-4.1.45.Final.jar:4.1.45.Final]
the IP address 172.28.0.2 is redis master ip in the docker image.
My sentinel host configuration is like below,
127.0.0.1:26379,127.0.0.1:26379,127.0.0.1:26379
I guess my application gets well the master info via localhost sentinel configuration.
Then Why is my application finding 172.28.0.2:6379 for master instead of 127.0.0.1:6379 ?
Do I need to change the address in that docker image or Should I run my app on the docker also?
Any help would be appreciated!
I just solved my problem by adding REDIS_MASTER_HOST=127.0.0.1 (thatw was 'redis' originally) at environment in docker-compose.
I figured out that there is 172.28.0.2 6379 set for monitor reids master in redis-sentinel.conf of running container and it didn't changed with container name 'redis'.
After that, my springb boot application with lettuce client can connect to redis without any problem in local machine.

Docker compose with Spring Boot Applications

I have two images- caller and callable.
When using docker compose and hitting the url of callable from caller image container, it is not working.
My docker compose file
version: "3.7"
services:
callerc:
image: caller:1.0
ports:
- "8000:8084"
environment:
- URL=callmec/callMe
callmec:
image: callable:1.0
ports:
- "5000:8082"
I get URI not absolute. When i try URL parameter as - http://callmec/callMe" then also it doens't work and says Connection refused.
But when I give the URL as my Machine IPv4 address - http://172.XX.XX.XX:5000/callMe then it works.
While trying "localhost:8000/callOtherService" gave Connection refused error - "callmec:5000/callMe": Connection refused
Kindly guide in case I have missed something.
You don't specify the port when you reference the container : http://callmec/callMe.
It uses the default HTTP port (80) such as http://callmec:80/callMe.
But no socket appears to listen that port on the callmec container.
What you want is : http://callmec:8082/callMe
callmec is not a name entry for 172.XX.XX.XX
If you want to use a local name for the Docker IP 172.XX.XX.XX then you have to add it to your hosts file:
On Linux you have to modify the /etc/hosts file.
Please read this document to see how you must do it on other OS: https://support.rackspace.com/how-to/modify-your-hosts-file/

docker ports not available

I have a spring-config-sever project that I am trying to run via Docker. I can run it from the command line and my other services and browser successfully connect via:
http://localhost:8980/aservice/dev
However, if I run it via Docker, the call fails.
My config-server has a Dockerfile:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=build/libs/my-config-server-0.1.0.jar
ADD ${JAR_FILE} my-config-server-0.1.0.jar
EXPOSE 8980
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/my-config-server-0.1.0.jar"]
I build via:
docker build -t my-config-server .
I am running it via:
docker run my-config-server -p 8980:8980
And then I confirm it is running via
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1cecafdf99fe my-config-server "java -Djava.securit…" 14 seconds ago Up 13 seconds 8980/tcp suspicious_brahmagupta
When I run it via Docker, the browse fails with a "ERR_CONNECTION_REFUSED" and my calling services fails with:
Could not locate PropertySource: I/O error on GET request for
"http://localhost:8980/aservice/dev": Connection refused (Connection
refused);
Adding full answer based on comments.
First, you have to specify -p before image name.
docker run -p 8980:8980 my-config-server.
Second, just configuring localhost with host port won't make your my-service container to talk to other container. locahost in container is within itself(not host). You will need to use appropriate docker networking model so both containers can talk to each other.
If you are on Linux, the default is Bridge so you can configure my-config-server container ip docker inspect {containerIp-of-config-server} as your config server endpoint.
Example if your my-config-server ip is 172.17.0.2 then endpoint is - http://172.17.0.2:8980/
spring:
cloud:
config:
uri: http://172.17.0.2:8980
Just follow the docker documentation for little bit more understanding on how networking works.
https://docs.docker.com/network/network-tutorial-standalone/
https://docs.docker.com/v17.09/engine/userguide/networking/
If you want to spin up both containers using docker-compose, then you can link both containers using service name. Just follow Networking in Compose.
I could imagine that the application only listens on localhost, ie 127.0.0.1.
You might want to try setting the property server.address to 0.0.0.0.
Then port 8980 should also be available externally.

Access a host from within a Docker container on Windows

I use Docker CE for Windows on latest Windows 10 and have built an image with a
script that runs a test against a web server.
(A litmus test suite for a WebDAV server to be exact, but I think the problem
is general.)
I run the web server on a Powershell console:
> wsgidav -p 8080 -H localhost
21:04:19.107 - <13348)> wsgidav INFO : Running WsgiDAV/3.0.0a3 Cheroot/6.4.0 Python/3.6.5
21:04:19.107 - <13348)> wsgidav INFO : Serving on http://localhost:8080 ...
From another Powershell console, I run my script in a Docker container (using FROM alpine).
The script starts and tries to access the endpoint, but does not succeed:
> docker pull mar10/litmus
> docker run --rm -p 8080:8080 mar10/litmus http://gateway.docker.internal:8080
-> running `basic':
0. init.................. FAIL (connection refused by `gateway.docker.internal' port 8080: Operation timed out)
I tried so far
Using the gateway.docker.internal hostname
using -p PORT:PORT
using --net=host
restarting the docker daemon (which interestingly sometimes also was neccessary to
fix timeouts in docker pull)
different IP addresses for the web server (127.0.0.1, localhost, 0.0.0.0, local IP)
Nothing worked so far (although the failure message may be different).
Maybe I just missed a working combination of the above, or any other trick?
FWIW, I was able to solve it by building the container with the --network host option and use a real IP of the client (instead of localhost or 0.0.0.0).
Details here: https://hub.docker.com/r/mar10/docker-litmus/

Resources