3

I have a spring boot application and I created dockerfile like this one :

FROM java:8
EXPOSE 80
ADD /target/test-server.jar test-server.jar
ENTRYPOINT ["java","-jar","test-server.jar"]

Next I follow these steps :

  1. docker build -t test-server .

  2. docker run -p 8888:80 -t test-server

and it works but on port 8080 , which is default to tomcat. I want it to run on 8888

Results from docker ps

3debfb5a9084        test-server       "java -jar test-ser"   About a minute ago   Up About a minute   0.0.0.0:8888->80/tcp   thirsty_euclid

Btw, why it shows test-ser rather than test-server ?

Generally, I want to be able to run this server on few different ports

Result from command

nmap -A -p8080,8888 localhost

is

Starting Nmap 7.12 ( https://nmap.org ) at 2016-12-05 20:49 CET
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000059s latency).
PORT     STATE  SERVICE    VERSION
8080/tcp closed http-proxy
8888/tcp open   tcpwrapped

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 5.45 seconds
msrd0
  • 7,816
  • 9
  • 47
  • 82
Mont
  • 165
  • 2
  • 3
  • 9
  • can you run `nmap -A -p8080,8888 localhost` outside docker and show us the result? – msrd0 Dec 05 '16 at 19:41
  • Something is wrong with this command, because I get Failed to resolve p8080,8888 – Mont Dec 05 '16 at 19:48
  • the command runs fine - did you forget the `-` in front of the p? – msrd0 Dec 05 '16 at 19:49
  • Yes, sorry about that. I updated my question – Mont Dec 05 '16 at 19:51
  • ok the output of nmap is that everything is doing what it should - where is your problem? – msrd0 Dec 05 '16 at 19:52
  • Can you explain how you are testing and seeing it listening on port 8080? – BMitch Dec 05 '16 at 19:53
  • @BMitch it is listening on port 8888, not 8080 according to nmap – msrd0 Dec 05 '16 at 19:54
  • Sorry I had to do something wrong, because now I see that it doesn't work on both ports - in browser I can't connect to it. If I run my app without docker it runs on 8080 and it works – Mont Dec 05 '16 at 19:59
  • if it runs on 8080 inside docker as well you should probably redirect port 8080 outside, not port 80 – msrd0 Dec 05 '16 at 20:02
  • Thanks. Now it works with command -p 8888:8080 but why ? I have EXPOSE 80 in my dockerfile – Mont Dec 05 '16 at 20:06
  • Your docker file doesn't control what port spring boot listens on, it's just a message to the docker host for what ports you should be listening on and is used by the `-P` option. – BMitch Dec 05 '16 at 20:08

2 Answers2

4

It's a bit difficult to understand from your comments, but it appears that your application is listening on port 8080 inside your container, but you've mapped port 8888 on the host to port 80 inside the container with docker run -p 8888:80 -t test-server. This will result in the unreachable port that you're seeing. You can map to port 8080 with:

docker run -p 8888:8080 -t test-server

Or, since you're using spring boot, you can set the value of server.port in your application properties to port 80 if you want to change the listening port.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • See [this question](http://stackoverflow.com/q/21083170/596285) for more details on setting the listening port in spring boot. – BMitch Dec 05 '16 at 20:07
2

There are different ports to take into consideration.

First there is your application that binds on a port. For spring boot this defaults to 8080, which is the port number the process is bound to inside the container.

With the EXPOSE instruction in your Dockerfile you say which ports should be exposed on the container's network interface. So if you start another container accessing the given one directly, you only get access to ports that are exposed. The exposed ports should in most cases match the port numbers the process inside the container binds to.

The third option is the port mapping you define when running a container. That basically says: Open a port on the docker host and route all traffic to the container on the latter port.

So all in all your current setup says:

  • open port 8888 on my docker host
  • map all traffic on 8888 of my docker host to the container's port 80
  • the container exposes port 80
  • in the container there is no process that is bound to port 80
  • the spring boot application is bound to port 8080 inside by default

So, there are different options. You can either expose port 8080 in your Dockerfile and map the ports as -p 8888:8080. If you want your process to run on a specific port inside the container, you can add the configuration property when starting the spring application like --server.port=8888. But be aware that this only affects the port where the java application is bound to and not which port you are accessing it later on. The EXPOSE must always match the internally used port to have access to the process running inside.

One additional information: By mapping a port like -p 8888:8080 you also open up the port 8080 on your container (which can be seen as some kind of exposing the internal port. What happens is the same. There is an iptables rule added such that the port of the container (here 8080) is accessible. So the EXPOSE instruction is relevant for container-to-container communication when there is no port mapping to the host.

Andreas Jägle
  • 11,632
  • 3
  • 31
  • 31