I am building a Spring Boot application for providing some REST services and I'd like to import it in Docker. If I run my application within IntelliJ pressing the run button, I can load the endpoints correctly.
My app is listening on the port 8091, as my dockerfile is the following
FROM openjdk:11
ADD out/artifacts/web_services_main_jar/web_services.main.jar lib_image.jar
EXPOSE 8091
ENTRYPOINT ["java","-jar","lib_image.jar"]
The code for building and running the docker container is the following
docker build --build-arg JAR_FILE=out/artifacts/web_services_main_jar/web_services.main.jar -t lib_proj .
docker run -p 8090:8091 lib_proj
The problem is that when the application is running in docker and I try to load "localhost:8090/user" in a browser, chrome returns the ERR_EMPTY_RESPONSE message.
If I open Docker and open the CLI of the container and I run
curl localhost:8091/user
even here an error is printed "curl: (7) Failed to connect to localhost port 8091: Connection refused". Any suggestion?
EDIT: my application.properties already specifies address and port as follows:
server.address=0.0.0.0
server.port=8091
Ok a workaround I found is to leave all the port to the default 8080. So i replaced the 8091 in the dockerfile and the 8090 in the "docker run ..." command to 8080 and now it works here. I assume because tomcat behind the scene only listens to this one, and I'm figuring out how to change this.
Related
I want to run a Java Spring application inside of a docker container and this application should be able to deploy sibling containers. When I run the Java application directly on my machine it works fine and can deploy containers, but as soon as I try to run the application inside a container it does not work any more (im using supervisord to run the mongodb and Java Spring app in one container and I know that thats not best practice). The container starts up fine, but crashes as soon as my application tries to connect to the docker deamon without any stacktraces from Java, just the error WARN received SIGTERM indicating exit request. The supervisord logs dont contain additional info.
I tried mounting the docker socket from the host (Windows 10 Pro with Docker Desktop, also tried Ubuntu Server 18.04) into the container using -v /var/run/docker.sock:/var/run/docker.sock.
I also tried to use --net="host".
Both did not work, although with the second one the container does not crash but produces a different error ({}->unix://localhost:80: Connection refused) visible in the log of my java application, which indicates that it cant even find the right address for the deamon.
I also activated "Expose deamon on tcp://localhost:2375 without TLS".
I also tried to set the DOCKER_HOST environment variable inside the container to default values such as "tcp://localhost:2375" or "/var/run/docker.sock".
Here is the code that I use to initialize the docker client.
DockerClient docker = DefaultDockerClient.fromEnv().build();
The DefaultDockerClient.fromEnv().build(); should create a docker client that uses the DOCKER_HOST environment variable to connect to the host or the default adress ("/var/run/docker.sock" on *NIX).
Here is my DOCKERFILE:
FROM openjdk:8-jre-alpine
ENV PACKAGES mongodb supervisor
VOLUME /opt/server
VOLUME /data/db
WORKDIR /opt/accservermanager
ADD supervisord.conf /etc/supervisor.conf
ADD accservermanager.jar /opt/accservermanager/accservermanager.jar
ADD application.properties /opt/accservermanager/application.properties
RUN apk update && \
apk add --update $PACKAGES --no-cache && \
rm -rf /var/cache/apk/*
EXPOSE 8000
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor.conf"]
And finally, my supervisord.conf
[supervisord]
user=root
stderr_logfile=/var/log/supervisord.err.log
stdout_logfile=/var/log/supervisord.out.log
loglevel=debug
[program:mongodb]
command=mongod --smallfiles
autostart=true
autorestart=true
stderr_logfile=/var/log/mongo.err.log
stdout_logfile=/var/log/mongo.out.log
[program:accservermanager]
directory=/opt/accservermanager/
command=java -jar accservermanager.jar
autostart=true
autorestart=true
stderr_logfile=/var/log/accservermanager.err.log
stdout_logfile=/var/log/accservermanager.out.log
Expected result: Application connects to the docker client from the host and is able to deploy/manage containers on the host
Actual result: Container crashes or outputs errors.
Turns out that there is a new version of spotify-docker that fixes my problem.
Updating from v8.15.1 to v8.15.2 solved my issue.
I have deployed a very simple MSSQL docker container using the following docker run command :
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=NotYourBusiness" -p 2433:1433 --name sql1 -d mcr.microsoft.com/mssql/server:2017-latest
I have SSMS installed on my machine and i'm able to connect to this instance with the following URL :
MyHostName,2433
I am able to run my spring boot app from my machine also with the following connection string :
dataSource.setJdbcUrl("jdbc:sqlserver://localhost:2433;database=SomeDatabase;");
With only MSSQL in a docker container, my application works perfectly from my machine.
Now, i want to put my spring boot app into a container as well. I have therefore built the following docker file :
FROM openjdk:11-jre-slim
VOLUME /tmp
EXPOSE 8082
ADD target/tno-1.0.jar tno-1.0.jar
ENTRYPOINT ["java","-jar","tno-1.0.jar"]
This is the build command i use to create the image :
docker build -f Dockerfile -t tno .
And this is the command i use to build the container :
docker run -t --name tno --link sql1:mssql -p 8082:8082 tno
Using the same connection string that works on my machine, the spring boot app fails to start with a connection refused error. I did look at many posts and they pointed out that the term "localhost" no longer really applies when running from a container since it refers to that container only. The only way i was able to make it work is to replace localhost:2433 with the container IP address : 1433.
This is perfectly acceptable but is there a way for a container to behave like my dev machine and be able to connect to another container as if the connection was coming from the outside world?
Thanks
If you can access to the database from the application running in other containers, try to configure your jdbc url from localhost to mssql (name of db link).
jdbc:sqlserver://mssql:2433;database=SomeDatabase;
Let me know or check this how to link container in docker?
I'm running my Docker container and expecting to hit it's endpoints.
In this question, I provided my Dockerfile and gradle.build.
How to improve gradle.build file?
The Docker image is built successfully and when I run it I see how Spring Boot is starting including "Spring Boot logo" and Tomcat started on port(s): 9090 (http) with context path ''
I run my image with pavelpolubentcev$ docker run -i -t -e SERVER_PORT=9090 messenger-auth-auth
Nevertheless, I'm not able to access my endpoints, when I try http://localhost:9090 then no "Could not get any response".
When I run docker ps -a I can see my image running:
9d31b3e2aa63 messenger-auth-auth "java -jar /app/mess…" 6 minutes ago Up 6 minutes 8080/tcp practical_nightingale
But for some reason I also see 8080/tcp
What should I do to run it properly and finally get answer from my endpoints?
Thanks for your help, I appreciate it, I really need to solve the issue.
The 8080/tcp you see on output when listing running containers is defined in EXPOSE on the image Dockerfile. But this instruction doesn't actually publish the port.
You have to map your host (machine) port to the container port in order to forward TCP/UDP from host to container.
That said, in your case, the command to run the container is:
docker run -e SERVER_PORT=9090 -p 9090:9090 messenger-auth-auth
Map the container port to an external port : docker run -p 9090:9090 ...
The first port is the outside port (which one you want to access now from the host machine) and the second is the inside port (the port on the container).
You can specify the same external port or not.
So I have dockerized a service "myxxx-service" along with Tomcat.
Dockerfile:
FROM tomcat:8-jre8
EXPOSE 8080
COPY ./myxxx-service/target/myxxx-service-1.0-SNAPSHOT.war /usr/local/tomcat/webapps
cmd mkdir -p /opt/myxxx/db
copy ./myxxx-service/src/test/resources/* /opt/myxxx/db/
CMD ["catalina.sh", "run"]
When I run the docker image, I am able to get the catalina.out logs. The tomcat becomes up. I am able to open the standard tomcat page on 8080 port.
But my service shows 404 error reponse.
I want to check my service specific logs that generally comes in the logs/myxxx-service.logs file.
Is there a way to do that?
Note: I have tried docker service logs. I am not sure if that works.
What's the output of your log? Is it file?
You can always get into the instance by:
docker exec -it <container-id/container-name> sh
And then you can navigate to your logs. If you use vendors like AWS then, in your container settings, you can use aws-log driver and send your logs to CloudWatch.
I have developed a small Java demo web app, using gradle, which I want to dockerize with WildFly. I have followed instructions from here.
The Dockerfile is:
FROM jboss/wildfly
MAINTAINER Me <me#qmail.com>
RUN /opt/jboss/wildfly/bin/add-user.sh admin Admin#70365 --silent
ADD build/libs/my-demo.war /opt/jboss/wildfly/standalone/deployments/
When I start the image with Docker and browse localhost:8080 or localhost:9990, I get a This site can’t be reached.
Yet, my application runs successfully on localhost:8080 when I use gradle appRun.
What is missing?
I am under Windows 10 Home Edition. I have tried on another laptop under Ubuntu 16 and face the same issue.
Three things:
1st
the base image EXPOSEs only port 8080, so to be able to access port 9990 you need to add EXPOSE 9990 to your Dockerfile or --expose 9990 to your docker runcall.
2nd
You didn't post your cmd line call, so I can only guess but you need to map the container port to a host port, example (including the additional exposed port)
docker run --expose 9990 -p 9990:9990 -p 8080:8080 -it my-demo
3rd
If your working with docker-machine as it is still the case with Win 10 home as far as I recall, you won't have your application on localhost but at the IP of the docker-machine VM. You can find out which IP that is by calling
docker-machine ip
On linux you will have your app on localhost:PORT once you add the port mapping.