I build a spring-server and a spring-client with eureka on docker and I try to connect the client to the server.
When I try this in my build.gradle:
docker {
maintainer = 'Me'
baseImage = 'java:8'
}
distDocker {
exposePort 8080
setEnvironment 'JAVA_OPTS', '-Dspring.profiles.active=docker'
}
everything works.
But I want to use the Dockerfile I wrote, so I use buildDocker instead of distDocker and I use it this way:
task buildDocker(type: Docker, dependsOn: build) {
dockerfile = file('src/main/docker/Dockerfile')
doFirst {
copy {
from jar
into stageDir
}
}
}
with this Dockerfile:
FROM java:8
ADD myjar-1.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
and that always leads to a
connection refused-error or more precisely to a ClientHandleException: Connection to http://localhost:8761 refused
I don't really understand where the problem is? If I don't try to connect to the server both ways work but if I try to connect only distDocker works.
The Spring Boot client app, running inside the container, is trying to reach localhost:8761, and since in the context of this Docker container 'localhost' refers to the container's address. There's nothing running on port 8761 of the container and hence you are seeing the connection refused error.
This might help:
Specify the location of Eureka in your client app's configuration via its application.yml:
eureka:
client:
serviceUrl:
defaultZone: <IP-address-of-Eureka-server>/eureka/
The <IP-address-of-Eureka-server> can be either an IP address or a host name that can be resolved from inside the container. If you want to pass the address of your host VM (the host that runs your Docker container), you can pass it as an environment variable using --env eureka.client.serviceUrl.defaultZone=xx.xx.xx.xx form. Something like this:
$ docker run ... --env eureka.client.serviceUrl.defaultZone=xx.xx.xx.xx
On a related note, if your Spring Boot client application also needs to register itself with Eureka, then you will need additional configuration to publish the resolvable host name and port of your Spring Boot app to Eureka. You can add the following to your application.yml:
eureka:
instance:
hostname: <client-host>
nonSecurePort: <client-port>
Where,
<client-host> is the resolvable host name of the client app container; and
<client-port> is the host VM's port that's bound to the exposed port of the container>
Again, you can pass these using the --env argument as shown above.
$ docker run -p 9001:8080 ... \
--env eureka.instance.hostname=yy.yy.yy.yy \
--env eureka.instance.nonSecurePort=9001
Be sure to set yy.yy.yy.yy to your VM's IP address.
If you want to test in your local machine then try with host ip address. To do that use the below configuration.
eureka.client.service-url.defaultZone=http://host.docker.internal:8761/eureka/
Related
I have a very simple Spring Boot service that has no authorisation, and should bypass CORS :
#RestController
public class MyController {
#CrossOrigin
#GetMapping(value = "/test")
public String test() {
return "hello";
}
I then run this in a docker container
If I do docker ps -a this is what I see :
I assume that if I want to call my /test service then all I would have to do is :
http://localhost:8080/test
I have also tried :
http://localhost:9090/test
http://localhost:90/test
http://0.0.0.0:9090/test
But I get nothing.
Is there some issue with my ports?
Looks like an issue with port exposing.
If you just want to expose the same port 8080 you could use the following command
--publish 8080:8080
It is enough to be accessible via the browser.
But the issue may also be with your application, so you can try to connect to it via an interactive terminal (i.e. not in detached mode) to see logs output:
docker run --interactive --tty --name shape-shop-back-end --publish 8080:8080 shape-shop-back-end_app-server
I do not see any issue in your attached screenshot. I do not feel it's a port issue.
Are your sure the request reaching to your rest application. Can you try to check the application log inside your docker container and see if the request is reaching there?
make sure that the port of your spring boot application is 8080 (by default it is 8080, but can be overriden in application.properties or application.yml)
make sure that you run docker container with the following command:
docker run -it -p8080:8080 image_name:image_version
where image_name and image_version correspond to the image you build or pull from docker hub
make sure that no other applicaiton is running on port 8080 (it could be any process, which is left running after incorrect shut down. On Windows I usually go to the process manager and shut down all running jvms, or you can use special tools to find id of the process, which runs on 8080 and shut it down). According to your screenshot, it doesn't look like there is a docker process running on 8080, but it can be any other process, so I wouldn't exclude this possibility.
I have recently started exploring the microservice architecture using jhipster and was trying to install and run the jhipster-registry from docker hub. Docker shows that the registry is running, but I am unable to access it on port 8761.
Pulled the image with docker pull jhipster/jhipster-registry
Started the container with docker run --name jhipster-registry -d jhipster/jhipster-registry
Here's a snapshot of what docker container ls returns:
Am I missing something over here?
You are starting the JHipster Registry container, but you aren't exposing the port.
You can expose a port by passing the port flag -p 8761:8761 which will enable you to connect to it via localhost:8761 or 127.0.0.1:8761 in a browser.
You may need to configure some environment variables for the JHipster Registry to start correctly. These may depend on your generated app's options, such as authentication type. For convenience JHipster apps come with a docker-compose.yml file. You can start it with docker-compose -f src/main/docker/jhipster-registry.yml up, as documented.
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.
I'm new to Docker and have access an API that runs on a container.
I'm running a container via:
cp -r ./lib app/
docker-compose up -d --build app
rm -fr app/lib/*
In my docker-compose.yml I do have the ports set to:
app:
build: ./app
container_name: my-app
ports:
- "9080:8080"
- "9990:9990"
- "6000:6000"
- "9877:9877"
- "1551:1551"
And a default ip for docker-machine: 192.168.99.100
I should be able to send requests to an api via https://192.168.99.100:8080/restapicall
What am I missing? Is there any way to expose ports to localost in shell script?
Few observations.
You are using wrong port number (8080) to access restapicall, In your docker-compose file, you are exposing port 8080 to 9080 (- "9080:8080").
Why are you using https? have you got SSL certificate set-up? if not try with http.
192.168.99.100 is this docker internal IP address? if yes then use your machine IP address or localhost?
Now try with below URL.
Use localhost if you are running docker on the same machine.
http://localhost:9080/restapicall
Use machine ip address if Docker is running on different machine.
http://machine-ip-address:9080/restapicall
If this doesn't work then please share your Docker file and docker-compose file.
A simple scenario:
2 eureka servers (http://archimedes1 http://archimedes2)
1 Config Server
1 Zull Gateway
1 Business Microservice
Deployed on localhost everything works as expected.
I dockerized them to run on individual containers for each app and tested on Docker over Windows.
What I see after deploying (config server, zull, and b-ms) is that if I dont specify eureka.instance.hostname for each of them they register in the Eureka servers with an invalid URL. This makes them impossible to call each other since they are getting invalid URLs.
For instance:
CONFIGSERVER n/a (1) (1) UP (1) - 287dd3ada410:configserver:8888
287dd3ada410:configserver:8888 points at 287dd3ada410:8888/info. And this doesn't exist.
To work around this I had to add to configserver's application.yml (and the equivalent for the other apps):
eureka:
instance:
hostname: config-server
Now it shows up in eureka like this:
CONFIGSERVER n/a (1) (1) UP (1) - c99cdfe9bd01:configserver:8888
And c99cdfe9bd01:configserver:8888 points at http://config-server:8888/info, which now resolves the config server correctly.
Why is it necessary to use eureka.instance.hostname for each service? Why don't they register with their IP:port as when running without Docker (c99cdfe9bd01:configserver:8888 -> 192.168.99.100:8888) ?
I believe each Docker container would need to register using the Docker host IP and Docker host port mapped to the container port.
This what I have used:
Eureka instance:
docker run -idt -p 8001:8001 --net=host -e spring.profiles.active=peerAware -e appPort=8001 -e hostName=$HOSTNAME -e dataCenter=asimio-cloud-dal -e environment=staging -e peerUrls="http://$HOSTNAME:8002/eureka/" asimio/discovery-server:1.0.73
A service instance:
docker run -idt -p 8601:8601 --net=host -e appPort=8601 -e hostName=$HOSTNAME -e eureka.client.serviceUrl.defaultZone="http://$HOSTNAME:8001/eureka/,http://$HOSTNAME:8002/eureka/" asimio/demo-registration-api-2:1.0.21
http://tech.asimio.net/2016/11/14/Microservices-Registration-and-Discovery-using-Spring-Cloud-Eureka-Ribbon-and-Feign.html#running-the-discovery-server-and-demo-services-in-docker-containers