Spring boot apps port mapping in docker container
Asked Answered
M

3

5

In my application.yml file, I added the server port on 8080.

server:
  port: 8080

Now in my Dockerfile, I am exposing port range 8080-8089. Here my goal is I will run this image on the different external and internal ports.

My Dockerfile is given bellow

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} user-service.jar
EXPOSE 8000-8089

ENTRYPOINT ["java","-jar","/user-service.jar"]

My docker image build command is given below:

docker image build -t user-service .

Now after building this image, my docker run command is given below:

docker run -d -p 8080:8080  -it user-service

Here, user-service is my docker image TAG. After this, I can access the app on 8080 port.

But the problem is when I run another container with port mapping -p 8081:8081, the application is running but won't access using port 8081.

My docker run command is:

docker run -d -p 8081:8081  -it user-service

Now my goal is I want to skip the application.yml server port with my external and internal port mapping in docker

Notes:

  1. This is .jar deployment. For WAR deployment we can easily skip the application.yml server port by server's configuration.
  2. I will change the port from the docker image to run container. I don't have scope to modify the application.yml file or Dockerfile after docker build

Thanks in advance

Miss answered 16/4, 2021 at 6:30 Comment(0)
M
7

Yes, finally I figured it out. For Spring boot embedded tomcat deployment, during running the container you have to set SERVER_PORT to override the application.yml server port property.

docker run -d -e SERVER_PORT=8081 -p 8081:8081  -it user-service
Miss answered 16/4, 2021 at 6:49 Comment(0)
H
20

Rather than providing an exact succinct solution, let me also explain why doesn't it work for you, I think it will be more valuable for our colleagues who will ever read this post.

So Starting with a spring boot part.

Spring boot knowns nothing about the docker.

When you put server.port: 8080 it only means that spring boot application starts the web server that is ready to get accept connections on that port.

If you want to change that mapping externally without modifying the application.yaml you can do that by passing the additional parameter:

java -jar myapp.jar --server.port=8081

This will effectively override the definition in yaml. There are other ways as well (environment variable for example). Spring boot supports many different ways of configurations and there are ways that take precedence over the configuration specified in yaml. Among them SERVER_PORT environment variable for exmaple.

You can read the official spring boot documentation chapter for more information

All the above happens regardless the presence of docker in the setup.

Now, as for the docker part.

When you run the container with -p A:B this means that it will forward the port A in the host machine to port B inside the container.

So this is why it doesn't work: you run

docker run -d -p 8081:8081 -it user-service

But no-one is ready to accept the connections on port 8081 inside the container. So its not precise to say that your docker service doesn't work - it starts but you can't call it.

So the simplest way wound be running with something like -p 8081:8080 so that from the host machine's standpoint the ports won't clash, but the container will be accessible.

If you want to also change the port in the docker container (for whatever reason) you can read the above about the spring boot part (with --server.port and everything)

Heptane answered 16/4, 2021 at 6:51 Comment(0)
M
7

Yes, finally I figured it out. For Spring boot embedded tomcat deployment, during running the container you have to set SERVER_PORT to override the application.yml server port property.

docker run -d -e SERVER_PORT=8081 -p 8081:8081  -it user-service
Miss answered 16/4, 2021 at 6:49 Comment(0)
C
2

EXPOSE directive in Dockerfile does nothing but hint which ports one should map. The reason why -p 8081:8081 didn't work is that your application listen on 8080 and not on 8081.

You should do -p 8081:8080 instead; this will map host's port 8081 to container 8080:

docker run -d -p 8080:8080 -it user-service
docker run -d -p 8081:8080 -it user-service
docker run -d -p 8082:8080 -it user-service
Cayes answered 16/4, 2021 at 6:49 Comment(1)
Brother, my goal was to map external port 8081 to internal port 8081. This was one of my businesses. Thanks for your answerMiss

© 2022 - 2024 — McMap. All rights reserved.