Docker: Get service specific logs deployed on Tomcat - java

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.

Related

Spring Boot application cannot run in Docker

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.

How to connect to the docker daemon on the host using spotify docker client

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.

Docker container is only able to access MSSQL running inside another container with the internal IP/port

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?

Why can't I access my endpoints 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.

Spring boot App not working after ssh logout

So I'm deploying my Spring Boot application on an Ubuntu LTS Server. It is built with maven and running with embedded Tomcat.
I'm still new to the deployment process, what I did was:
Log into server via ssh
use scp to upload my_application.zip
unzip it in ssh
java -jar my_application.jar
Now all of that works perfectly fine and I've been using it like that for quiet some time. Now I have to make the Application to stay online and available after logging out of the shell.
I have read some documentation about running processes in background on Linux and I've tried it with nohup java -jar myApplication.jar &, with the screen command and with bg. All of them worked fine while I'm logged into the ssh.
Here comes my problem:
As soon as I end the ssh session the Web App is still available (so the process clearly didn't stop) but it just looks & behaves really weird.
CSS is not applied, JS does not work etc.
My guess would be that some paths or file system accesses are messed up, but I have no idea at all how that could origin from the ssh session.
(When I log back into ssh everything is working fine again)
Would be great if someone has a clue here
If your server has encrypted home directory, it will get re-encrypted once you log out and therefore your script will stop working. It does not have a lot of sense to have encrypted homes on servers so you can disable it.
Or just run the script from different directory and avoid working with files under home directory.
I think you should use systemd for this case.
Also You can add new system user for your app.
You can find more information here:
Spring Boot: 59.2.2 Installation as a systemd service
Ubuntu Wiki: Systemd For UpstartUsers
For example:
Create file myunit.service
[Unit]
Description=MySpringService
After=syslog.target
After=network.target
After=mysql.service
[Service]
Type=forking
PIDFile=/work/www/myunit/shared/tmp/pids/service.pid
WorkingDirectory=/work/www/myunit/current
User=myunit
Group=myunit
Environment=RACK_ENV=production
OOMScoreAdjust=-1000
ExecStart=/usr/local/bin/bundle exec service -C /work/www/myunit/shared/config/service.rb --daemon
ExecStop=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state stop
ExecReload=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state restart
TimeoutSec=300
[Install]
WantedBy=multi-user.target
Copy file to /etc/systemd/system/
Run:
systemctl enable myunit
systemctl start myunit

Categories

Resources