I want to access my website from a Docker container but I can\'t. The steps I am trying to implement are as follows. After all the steps I can\'t access the http://loc
To fully address your question (dockerize a Spring Boot project and browse the corresponding webapp in the local browser during, say, development phase), three independent tasks have to be done:
Leverage the build of the Docker image by using a Dockerfile
that benefits from Docker's cache mechanism (to avoid re-downloading Maven dependencies from scratch every time, and thereby speed-up the build)
Make sure the Spring Boot app listens to the specified port for the 0.0.0.0
special IP, not localhost
;
And finally publish the given port so that you can run for example:
$ xdg-open http://localhost:8080/index
Step 3 is well explained in @Poger's answer, so I'll elaborate a bit more on the steps 1 and 2 only:
I have proposed a Dockerfile
in this SO thread: How to cache maven dependencies in Docker, inspired by this blog article, that is applicable for Java/Maven projects in general (not only Spring Boot projects):
# our base build image
FROM maven:3-jdk-8 as maven
WORKDIR /app
# copy the Project Object Model file
COPY ./pom.xml ./pom.xml
# fetch all dependencies
RUN mvn dependency:go-offline -B
# copy your other files
COPY ./src ./src
# build for release
# NOTE: my-project-* should be replaced with the proper prefix
RUN mvn package && cp target/my-project-*.jar app.jar
# smaller, final base image
FROM openjdk:8-jre-alpine
# OPTIONAL: copy dependencies so the thin jar won't need to re-download them
# COPY --from=maven /root/.m2 /root/.m2
# set deployment directory
WORKDIR /app
# copy over the built artifact from the maven image
COPY --from=maven /app/app.jar ./app.jar
# set the startup command to run your binary
CMD ["java", "-jar", "/app/app.jar"]
but to refine it further, note that it's recommended to pass an extra system property java.security.egd:
CMD ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/app.jar"]
or if you prefer ENTRYPOINT
over CMD
:
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/app.jar"]
As mentioned in the SO thread How do I access a spring app running in a docker container?, in the context of a containerized application, localhost
should be avoided and replaced with 0.0.0.0
most of the time (namely, if the app should act as a web service replying to incoming requests from outside the container).
To sum up, you should just try adding the following line in your application.properties
file:
server.address=0.0.0.0
When you run a Docker container, all the ports, which any application happen to listen on within it, are not published by default.
In order to publish a port, you need to specify it while running the container using your image. For all the details on how to do it, you can check the "EXPOSE" section in the documentation of docker run command: https://docs.docker.com/engine/reference/run/
Shortly speaking, you want to add another option while running your container:
docker run --name mycontainer1 -p 8080:8080 myimage1
I'm not sure if you wanted to achieve this by adding
EXPOSE 8080
in your Dockerfile. Actually, this does not mean that the port will be exposed when the image is used to run a container. As you might find in Dockerfile reference:
The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports.