Running Spring boot application inside docker container - java

I have created an image out of my simple spring-boot application and set the port to 7000 for the tomcat , when I run the image and try to hit the service in my local I am not getting any response.
here are the contents of the dockerfile
FROM java:8
VOLUME /tmp
ADD /target/demo-1.0-SNAPSHOT.jar /app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Am I missing something here ( I am new to docker and I just used the file in spring boot sample docker and created the image and stuck here.)

Apart from publishing the port from docker as mentioned by #Van0SS you need to create a port forwarding rule as well.
Open virtualbox and Navigate to VM -> Settings -> Network -> Advanced -> Port forwarding
Create a new rule:
Name : <Anything - Purpose of port>
Protocol: TCP
HostIP: 127.0.0.1
Host port: 7000
Guest Port: 7000

Not sure that it is only one problem, but at least you have to publish your port in docker. To do so run the container with flag:
-p 7000:7000
Try access on :7000 port.

You need to add:
EXPOSE: 7000
to your docker file, and keep an eye on the console log info when running the docker image to see on which port your app is being served.
Useful Ref:
https://www.youtube.com/watch?v=FlSup_eelYE
Best of luck!

Related

Spring + Prometheus + Grafana: Err reading Prometheus: Post "http://localhost:9090/api/v1/query": dial tcp 127.0.0.1:9090: connect: connection refused

Hello I have an app in Spring Boot and I am exposing some metrics on Prometheus. My next goal is to provide these metrics on Grafana in order to obtain some beautiful dashboards. I am using docker on WSL Ubuntu and typed the next commands for Prometheus and Grafana:
docker run -d --name=prometheus -p 9090:9090 -v /mnt/d/Projects/Msc-Thesis-Project/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus --config.file=/etc/prometheus/prometheus.yml
docker run -d --name=grafana -p 3000:3000 grafana/grafana
Below I am giving you the Prometheus dashboard in my browser and as you can see, everything is up and running. My problem is in Grafana configuration where I have to configure Prometheus as Data Source.
In the field URL I am providing the http://localhost:9090 but I am getting the following error:
Error reading Prometheus: Post "http://localhost:9090/api/v1/query": dial tcp 127.0.0.1:9090: connect: connection refused
I've searched everywhere and saw some workarounds that don't apply to me. To be specific I used the following: http://host.docker.internal:9090, http://server-ip:9090 and of course my system's IP address via the ipconfig command http://<ip_address>:9090. Nothing works!!!
I am not using docker-compose but just a prometheus.yml file which is as follows.
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']
- job_name: 'Spring Boot Application input'
metrics_path: '/actuator/prometheus'
scrape_interval: 2s
scheme: http
static_configs:
- targets: ['192.168.1.233:8080']
labels:
application: "MSc Project Thesis"
Can you advise me something?
You can use the docker inspect command to find the IP address of the Prometheus container and then replace the localhost word with it.
I'll suggest you to use docker-compose, which better supports in DNS resolving and your issues of localhost will get resolved.
It works for https://stackoverflow.com/a/74061034/4841138
Also, if you deploy the stack by docker compose and all dockers are in same network, you can do that:
URL: http://prometheus:9090
In above, prometheus is the domain name of the prometheus docker, which can be resolved by all dockers within same network.

Web server failed to start. Port 8080 was already in use. Spring Boot microservice

I am trying to call webAPI from gradle project.
My build.gradle is as following.
plugins {
id 'org.springframework.boot' version '2.1.4.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
compile 'org.springframework.boot:spring-boot-starter-webflux'
compile 'org.projectreactor:reactor-spring:1.0.1.RELEASE'
}
If I remove following dependency
compile 'org.springframework.boot:spring-boot-starter-webflux'
It works, but if I add it back. it gives error as
Web server failed to start. Port 8080 was already in use.
So, how do I fix this, so that I can use webclient? Because application is not web application which requires port to run. it is a sort of microservice.
I just want to use WebClient of Spring Boot. How do i use it without converting my application into web application.
If on windows and your getting this every time you run the application you need to keep doing:
> netstat -ano | findstr *<port used>*
TCP 0.0.0.0:*<port used>* 0.0.0.0:0 LISTENING *<pid>*
TCP [::]:*<port used>* [::]:0 LISTENING *<pid>*
> taskkill /F /PID *<pid>*
SUCCESS: The process with PID *<pid>* has been terminated.
If netstat above includes something like this;
TCP [zzzz:e2ce:44xx:1:axx6:dxxf:xxx:xxxx]:540yy [zzzz:e2ce:44xx:1:axx6:dxxf:xxx:xxxx]:*<port used>* TIME_WAIT 0
Then you can either wait for a little while or reconfigure to use another port.
I suppose we could write some code to randomly generate and check if a port is free when the application runs. Though this will have diminishing returns as they start to get used up. On the other hand could add a resource clean up code that does what we have above once the application stops.
You can change the default port of your application in application.properties by adding the following line:
server.port = 8090
If you don't want the embedded server to start, just set the following property in you application.properties (or .yml):
spring.main.web-application-type=none
If your classpath contains the necessary bits to start a web server, Spring Boot will automatically start it. To disable this behaviour configure the WebApplicationType in your application.properties
Source: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-web-servers.html
If you application really is a Web application, then you can easily change the port using the server.port property (in your application's .properties/.yaml file, as a command line argument at startup, etc).
Another way to do this is by first checking what processes are using that specific port, then killing it using its process ID:
Run lsof -i :8080
This will identify which process is listening on port 8080.
Take note of the process ID (PID) e.g. 63262
Run kill -9 <PID> e.g. kill -9 63262
Some time if you can manually kill the that port problem can solve.
Using CurrPorts software you can view what are the running all ports in your machine and you can kill that port if you want.
You can download CurrPorts from here. (download link is in bottom of the page)
============== OR ==============
Without CurrPorts you can do this using like below method also.
CMD as run as administrator
Enter netstat -a -o -n and hit enter. Now you can see like below. Port can see Local Address column after : sign.
select the process id(not port) that your port running and type taskkill /F /PID <process_id_here> command and hit enter.
You can use npm to kill the port
**npx kill-port 8080** //8080 for example
Requirement: npm
read more: https://www.npmjs.com/package/kill-port
create /resources folder inside src/main
create application.properties file inside /resources
write server.port=9090 //(use any port number of your choice)
if port:8080 already in use error occurs:
goto command prompt
.type command> .netstat -ano
.Enter->this will show all running port check port 8080
.type command> taskkill /F /PID 8080
.process will terminate.
you can set server.port= #some-available-port number in application.properties file
or run command prompt in administrator mode and run netstat -a -o -n.
Find the process id which is using port 8080.
Run taskkill /F /PID #Processid command
It's easy we have two methods to solve.
First one is to change the port number in your application.properties i.e
server.port=9999 // something like this...
and second is, to first stop the available running server and then re-run your server again.
I am sure it work :)
If you had previously started the spring boot app and forgot to stop before hitting play again then Go to windows task manager and locate the java application(Something like "OpenJDK Platform binary" and click on End Task. (Java app not eclipse). Then try running again. It worked for me.
open command prompt as administrator
step1: netstat -ano | findstr :<enter your 4 digit port number>
netstat -ano | findstr :8080
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 6436
TCP [::]:8080 [::]:0 LISTENING 6436
step2: taskkill /PID <enter above pid number(sometimes it shown 3/4/5/6 digits)> /F
taskkill /PID 6436 /F
SUCCESS: The process with PID 6436 has been terminated.
To reset port 8080, you need to find PID (Process ID) and specify it for the command as, for example, on the screen 10512:
taskkill /F /PID 10512
You try to use an already used port.
Ports are used on the transport layer - tcp, http is application layer and uses a transport layer to send and receive requests.
Default port exposed by spring boot app is 8080. In your case you have two solutions:
change port for your application
stop the service that uses the port you want to use
to catch java.net.BindException e with message: Address already in use and to start on other available port and to use webclient with one of 2 ports.
try {
SpringApplication.run(Application.class, args);
} catch (org.springframework.boot.web.server.PortInUseException e) {
//Runtime.exec("pkil")..
//or
SpringApplication.run(Application.class, otherargs);
//SpringApplication.run(Application.class, new String[]{"--server.port=8444"});
//when invoked recursively it is a port rebalancer for port usage among port pool with server as from client for startup stage via application restarts within many busy ports which are used before or without querying.
}
The error basically means that your port 8080 is occupied. If you are getting this error then go to your project and open application.properties and add the below line and it should work fine:
server.port = 8090
Your client application also spring boot application, whats why you have two spring boot application run in 8080 port.
Change port one of them or create a standalone java application with main class, put your web client in it and run.
As http client you can use Apache Http Client.
Today I was working in Spring Boot project and I got the same error in my project. So, what I did, I clicked on stop button beside the run last tool button and run again. Then, my project started working very well.
You can also write services.msc in your search bar in windows.Then you can find Apache Tomcat and then just stop this apache. I think its gonna be work.
It is a simple answer.If you are getting this error then go to your project then
src/main/resources and open application.properties file and mention there
server.port=8045 you can give your own number here instead of 8045
thanks
Open cmd and type "netstat -ano -p tcp."
Then, look for the port number and PID.
Open up Resource Monitor and search for the PID number
Right Click and "End Process."
Restarting my machine solved the issue although I was getting below issue:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'; nested exception is org.springframework.boot.web.server.PortInUseException: Port 8081 is already in use
If you getting this error again and again , then make sure server.port=(your port no) is the first line in application.properties file.
The best answer to this is to always use the "Relaunch Application" button. That will stop the web server and restart the entire app on the same port as before.
It's the button with the red square and green play icon combined.
https://i.stack.imgur.com/ICGtX.png

spring boot Eureka microservice discovery and registration fails in docker

I created a eureka server microservice and a normal microservice , usually when I run both the service separately using STS tool service discovery and registration works fine , but whenever i tried to launch in docker that time registration fails.
Code is below -
Eureka Server
application.properties
spring.application.name=eureka-service
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.instance.hostname=eureka-service
eureka.instance.prefer-ip-address=true
eureka.server.wait-time-in-ms-when-sync-empty=0
Dockerfile
FROM openjdk:8
ADD target/SpringEureka-1.0.jar SpringEureka-1.0.jar
EXPOSE 8761
ENTRYPOINT ["java","-jar","SpringEureka-1.0.jar"]
Normal Microservice
application.properties
server.port: 8010
spring.application.name=eureka-client
eureka.client.register-with-eureka=true
eureka.client.fetch-registry= true
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
eureka.client.proxy-host=localhost
eureka.instance.prefer-ip-address=true
Dockerfile
FROM openjdk:8
ADD target/HystrixTest-1.0.jar HystrixTest-1.0.jar
EXPOSE 8010
ENTRYPOINT ["java","-jar","HystrixTest-1.0.jar"]
Are you link the HystrixTest container to Eureka Server container?
You can get more detail in here: https://docs.docker.com/network/links/
The better question if you post docker-compose file or your cmd when starting the container.
I think everything that you did is all right you just need to enable the ports using the
docker run -P 8761:8761 <your_docker_image> command.
And change also the configuration from eureka.instance.hostname=eureka-service to eureka.instance.hostname=localhost

Remote Debug for Cloud Foundry application fails when connecting eclipse remote debugger to forwarded local port

I'm trying to remotely debug a Spring boot application deployed on a cloud foundry Instance. Below are the steps that I'm following to setup remote debug using eclipse:
Setting up JBP_CONFIG_DEBUG: '{enabled: true}' environment variable for the application.
After that I'm setting up the local port forwarding to my app container with cf ssh -N -T -L 8000:localhost:8000 <APP_NAME>
Then I'm setting up the remote debug configuration in eclipse as shown below image:Eclipse remote debug setup
After that when I try to start remote debug session, It tried to connect to the app but fails with the message at the port forwarded terminal:
connect to localhost:8000 failed: ssh: rejected: connect failed (dial
tcp 127.0.0.1:8000: getsockopt: connection refused)
Please help, if anyone has any clue about this error!!
You might have to restage the application for the change to take place, debug configuration to change.
You can use alternatively ssh into the container using cf ssh <application name> and check that the debug port is opened on not using netstat -an
We had some issues as well, but with a specific java buildback, but anyway mabe it'll help you in your case as well, try:
cf set-env <app-name> JBP_CONFIG_JAVA_OPTS '[java_opts: "-XX:+ForceDebuggingOnDemand"]'
cf restage <app-name>
try to change debugging port like this:
JBP_CONFIG_DEBUG "{enabled: true, port: 8001}"

Docker port isn't accessible from host

I have a new Spring Boot application that I just finished and am trying to deploy it to Docker. Inside the container the application works fine. It uses ports 9000 for user facing requests and 9100 for administrative tasks like health checks. When I start a docker instance and try to access port 9000 I get the following error:
curl: (56) Recv failure: Connection reset by peer
After a lot of experimentation (via curl), I confirmed in with several different configurations that the application functions fine inside the container, but when I try to map ports to the host it doesn't connect. I've tried starting it with the following commands. None of them allow me to access the ports from the host.
docker run -P=true my-app
docker run -p 9000:9000 my-app
The workaround
The only approach that works is using the --net host option, but this doesn't allow me to run more than one container on that host.
docker run -d --net=host my-app
Experiments with ports and expose
I've used various versions of the Dockerfile exposing different ports such as 9000 and 9100 or just 9000. None of that helped. Here's my latest version:
FROM ubuntu
MAINTAINER redacted
RUN apt-get update
RUN apt-get install openjdk-7-jre-headless -y
RUN mkdir -p /opt/app
WORKDIR /opt/app
ADD ./target/oauth-authentication-1.0.0.jar /opt/app/service.jar
ADD config.properties /opt/app/config.properties
EXPOSE 9000
ENTRYPOINT java -Dext.properties.dir=/opt/app -jar /opt/app/service.jar
Hello World works
To make sure I can run a Spring Boot application, I tried Simplest-Spring-Boot-MVC-HelloWorld and it worked fine.
Netstat Results
I've used netstat to do port scans from the host and from the container:
From the host
root#my-docker-host:~# nmap 172.17.0.71 -p9000-9200
Starting Nmap 6.40 ( http://nmap.org ) at 2014-11-14 19:19 UTC Nmap
scan report for my-docker-host (172.17.0.71)
Host is up (0.0000090s latency).
Not shown: 200 closed ports
PORT STATE SERVICE
9100/tcp open jetdirect
MAC Address: F2:1A:ED:F4:07:7A (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 1.48 seconds
From the container
root#80cf20c0c1fa:/opt/app# nmap 127.0.0.1 -p9000-9200
Starting Nmap 6.40 ( http://nmap.org ) at 2014-11-14 19:20 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000070s latency).
Not shown: 199 closed ports
PORT STATE SERVICE
9000/tcp open cslistener
9100/tcp open jetdirect
Nmap done: 1 IP address (1 host up) scanned in 2.25 seconds
The container is using Ubuntu
The hosts I've replicated this are Centos and Ubuntu.
This SO question seems similar but had very few details and no answers, so I thought I'd try to document my scenario a bit more.
I had a similar problem, in which specifying a host IP address as '127.0.0.1' wouldn't properly forward the port to the host.
Setting the web server's IP to '0.0.0.0' fixes the problem
eg - for my Node app - the following doesn't work
app.listen(3000, '127.0.0.1')
Where as the following does work:
app.listen(3000, '0.0.0.0')
Which I guess means that docker, by default, is exposing 0.0.0.0:containerPort -> local port
You should run with docker run -P to get the ports to map automatically to the same values to set in the Dockerfile.. Please see http://docs.docker.com/reference/run/#expose-incoming-ports

Categories

Resources