SIGTERM is not received by the java process using ‘docker stop’ and the official JAVA image
I use Debian / Jessie based image Java: 7u79 to run the dropwizard Java application in the docker container
My java application handles SIGTERM signals and shuts down normally When I run an application without docker, SIGTERM processing function is perfect
When I run it in the docker container, SIGTERM will not reach the Java application when I issue the docker stop command After 10 seconds, it will die suddenly
My docker file:
FROM java:7u79 COPY dropwizard-example-1.0.0.jar /opt/dropwizard/ COPY example.keystore /opt/dropwizard/ COPY example.yml /opt/dropwizard/ WORKDIR /opt/dropwizard RUN java -jar dropwizard-example-1.0.0.jar db migrate /opt/dropwizard/example.yml CMD java -jar dropwizard-example-1.0.0.jar server /opt/dropwizard/example.yml EXPOSE 8080 8081
What's wrong with this docker file? Is there any way to solve this problem?
Solution
Suppose you start a Java service by defining the following in dockerfile:
CMD java -jar ...
When you enter the container and list the process, you can see that your Java process is not the root process (not the process of PID 1), but the child process of / bin / sh process through docker exec - it < containername > PS AHF (I didn't try to use Java but used Ubuntu image):
UID PID PPID C STIME TTY TIME CMD root 1 0 0 18:27 ? 00:00:00 /bin/sh -c java -jar ... root 8 1 0 18:27 ? 00:00:00 java -jar ...
So basically you have a Linux shell, which is the main process of PID 1. It has a sub process (Java) with PID 8
For signal processing to work properly, you should avoid these shell parent processes This can be done by using the built - in shell command exec This will cause the child process to take over the parent process So in the end, the previous parent process no longer exists And the subprocess becomes the process of PID 1 Try the following in dockerfile:
CMD exec java -jar ...
The process list should be as follows:
UID PID PPID C STIME TTY TIME CMD root 1 0 0 18:30 ? 00:00:00 java -jar ...
Now you have only one process with PID 1 Generally speaking, a good practice is to make the docker container contain only one process - a PID 1 (or if you really need more processes, you should use, for example, supervisor as PID 1, which itself takes care of the signal processing of its child processes)
With this setting, SIGTERM will be processed directly by the java process No shell processes may interrupt signal processing
Edit:
Implicitly achieve the same execution effect by using different CMD syntax (thank Andy for his comments):
CMD ["java","-jar","..."]