16

I am building a Spring Boot application, which has a few different REST endpoints. It can be locally packaged and launched as a jar file successfully. When running locally, I can access its endpoints via "http://localhost:8080/endpoint?params..". I was tasked with now preparing this application to run off of Dockers. Still working on my local machine, I have created a Dockers container based off of the Java:8 image. In this container, I have been able to run my application from the .jar successfully. My issue is, I do not understand how to call to the REST endpoints inside the application, when the application is hosted off of Docker, since logically localhost:8080/endpoint is no longer responsive to the call.

Side information: My local computer is Windows, the Docker image is Ubuntu (eventually will be launched onto a Linux server).

UPDATE: Created a new image with the following Dockerfile:

FROM openjdk:8
MAINTAINER  My Name email@email.com
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
EXPOSE 8080
RUN javac Main.java
CMD ["java", "Main"]

Same issue, cannot access endpoint via http://localhost:8080/endpoint

Any help will be appreciated. Thank you!

Andy Shinn
  • 26,561
  • 8
  • 75
  • 93
dFrancisco
  • 896
  • 1
  • 11
  • 21
  • 2
    Did you do something like `EXPOSE 8080` in your Dockerfile ? – Gregg Jun 27 '17 at 15:51
  • @Gregg I did not create the image, hence I am unsure what the Dockerfile contains. I followed the tutorial here: https://octoperf.com/blog/2016/02/11/small-java-docker-images/ which explained to run the command "docker pull java:8" – dFrancisco Jun 27 '17 at 15:57

2 Answers2

18

You need to publish the port (not EXPOSE it). Exposing a port is largely used for links and service contexts. In your example of just running a Docker container, you need to simply publish the port so it is available from the host. You do this with --publish or -p:

docker run -d --name myapp -p 8080:8080 myappimage

Then you can access the application at port 8080 on the host IP address (Docker on Windows and Docker on Mac run a proxy that should allow localhost:8080 to work).

Andy Shinn
  • 26,561
  • 8
  • 75
  • 93
  • If I run the command: "docker run -d --name someName -p 8080:8080 imageName" it returns a long string of what appears to be random characters i.e. "a3431a0089937d5fc" etc. for another 30 characters or so, then the command line returns for me to write another command. Seems un-expected. Any idea what it is doing? – dFrancisco Jun 27 '17 at 17:19
  • That long string is the container ID. In my example I used `-d` which runs the container in the background. You should be able to see it with `docker ps` (or `docker ps -a` if it isn't running). You can use `docker stop ` and `docker rm ` to remove it. Then, if you remove the `-d`, it will run in the foreground instead. – Andy Shinn Jun 27 '17 at 17:44
  • It works now! I needed it to run in the foreground to navigate to the jar and run it. Now that I can/have, I can call the endpoint through localhost like normal. Thank you! – dFrancisco Jun 27 '17 at 17:57
  • One more question. I have a local Maria DB available at localhost:3308 which is called by the application. Now that this is running in Dockers, the connection is being refused. Any idea why? – dFrancisco Jun 27 '17 at 18:06
  • `localhost` is now the local IP of the container and not the host. You will need to connect to the host IP or the Docker bridge IP (which is usually `172.17.42.1`). – Andy Shinn Jun 28 '17 at 00:45
  • Buts we also specify port in `Dockerfile`? For what purpose that port is used? – Faizan Mubasher Feb 25 '20 at 12:56
1

If your application is running inside of a Docker Container and you can access from inside this container using localhost:8080, then all you have to do is add the EXPOSE instruction in your DOCKERFILE (see Dockerfile expose option).

EXPOSE 8080

Then you probably will be able to access from the host machine (where Docker is installed and running) using the default IP from the docker0 network interface. Generally this IP is 172.17.0.X, where X is 2 for your first container, and so on (see docker default networking).

So try to access from outside of the docker using "http://172.17.0.2:8080/endpoint?params..". Also, if you want to allow external access (or access using localhost from the host machine) you should start your container mapping the port from the EXPOSE instruction by using -p parameter (see Mapping Exposed Incoming Ports).

Jairton Junior
  • 674
  • 6
  • 16
  • How could I test if I could access it from within the container? Once I run the jar (the application) within the container, I cannot run other commands as the jar's running will take over the command line. Therefore, I cannot try to run a command to access localhost:8080/endpoint, so I do not know how to test this – dFrancisco Jun 27 '17 at 16:24
  • Start your application in background: `java -jar application.jar > log.txt 2>&1 & `. Then you can use "curl" or "wget" to access your service – Jairton Junior Jun 27 '17 at 16:29
  • This is not really how `EXPOSE` works. See https://stackoverflow.com/questions/22111060/difference-between-expose-and-publish-in-docker. – Andy Shinn Jun 27 '17 at 16:48
  • I see. I actually never tried to publish without exposing a port before hand. But in his case, where he probably exposed the port (because it is in the tutorial) he could try to access using docker0 ip without having to publish... – Jairton Junior Jun 27 '17 at 16:58