问题
I'm running tomcat in docker, but I can't see the logs. They are written to various log files under tomcat/logs, but I can't see them when tomcat is running in a docker container.
Here is my Dockerfile
FROM tomcat:7-jre8
COPY target/MYAPP.war /usr/local/tomcat/webapps/MYAPP.war
RUN ["/usr/local/tomcat/bin/catalina.sh", "start"]
This is how I build image & start container from it:
docker build -t MYAPP .
docker run -it --rm -p 8080:8080 --name MYAPP MYAPP
My app creates log file: /var/log/MYAPP.log after tomcat deploys MYAPP.war
How should I amend Dockerfile and which command should I use to run it ("docker run ...") so that right after starting the container MYAPP using the oneliner "docker run -it --rm -p 8080:8080 --name MYAPP MYAPP" the contents of /var/log/MYAPP.log would be printed to stdout?
I tried to add to Dockerfile the command below but it didn't help.
CMD tail -f /usr/local/MYAPP.log
回答1:
You seem to be confused about the different between RUN
and CMD
.
The RUN
directive is used to run commands during the build process. It is never executed in a container. When you write...
RUN ["/usr/local/tomcat/bin/catalina.sh", "start"]
...this means that during the docker build
process, Docker will start tomcat, but will immediately kill it and continue to build your image.
Only the CMD
and ENTRYPOINT
directives define commands that will be run when you boot an image with docker run
. So possibly you want something like:
CMD /usr/local/tomcat/bin/catalina.sh start && tail -f /usr/local/MYAPP.log
回答2:
Ok, your dockerfile should contain something like this**:
from tomcat:7-jre8
copy target/myapp.war /usr/local/tomcat/webapps/myapp.war
entrypoint ["/bin/bash", "/usr/local/tomcat/bin/catalina.sh", "run"]
Then you can run a container based on this image with something like:
docker run -itd -p 8080:8080 --name aname animage
So, the catalina 'run' command is designed to redirect all logs to stdout. This is useful to us because this is how docker works. If you run the container now you'll be able to run:
docker logs aname
The output will be anything that has been sent to stdout within the container. You can do with this what you wish, but common strategies are transporting the logs to logstash, splunk, or a thousand other places, or you could write them to a file (though that last one is mostly for developers).
** Of course, you'll have to change the entrypoint to match the specifics of your installation. And the run command I've shown here is for a daemon.
Original problem:
Your original problems were based on a common mistake; you were trying to run the tomcat server during provisioning (building the image). You actually want to run the server when you run the container. So, I've removed the run
and replaced it with an entrypoint, which is the correct way of running a command like this. Finally, cmd
is for passing parameters to the entrypoint, which we don't need in this case.
Finally, I've chosen to use cataline.sh run
rather than start
because run
is designed to send the logs to stdout rather than a file, as start
does.
References
View logs: https://docs.docker.com/config/containers/logging/
Conf logs: https://docs.docker.com/config/containers/logging/configure/
回答3:
May be it will be better to write logs directly to the stdout instead of the file in the container. It will be lost after restart.
See for more details https://12factor.net/logs
来源:https://stackoverflow.com/questions/47715280/tomcat-docker-logging-and-stdout