Closed sbreakey closed 2 years ago
Another possible solution, that may be a bit better than swapping JAVA_OPTS
for JAVA_TOOL_OPTIONS
as mentioned above, is to change the entrypoint to:
ENTRYPOINT ["sh", "-c", "exec java ${JAVA_OPTS} -jar /app.jar"]
Instead of spawning a child process, exec
replaces the current process, thereby retaining PID 1 for the java process itself so it receives the SIGTERM directly.
It's funny because I find that the Java process gets the SIGTERM even without an "exec". I wonder what might be different? Do all processes get SIGTERM when process 1 dies? (Note that the "exec" form was used in the run.sh
example in this guide for precisely the reason you outlined. It just didn't seem necessary empirically for the literal entry point style.)
I'm pretty sure it works as described. To verify:
$ docker exec -ti myapp /bin/sh
/ # ps -elf
PID USER TIME COMMAND
1 root 0:11 java -jar /app.jar
31 root 0:00 /bin/sh
38 root 0:00 ps -elf
@dsyer thanks for updating this. Could it be dependent on the linux distro in use?
I see the example in the docs is FROM eclipse-temurin:17-jdk-alpine
, and when i try test this with that base image, my results are as per yours.
However in my case, our base images are FROM ubuntu:18.04
, and if I leave off the exec in my ENTRYPOINT, like so: ENTRYPOINT [ "sh", "-c", ". /expandEnvSecrets.sh && java $JAVA_OPTS -jar /application.jar"]
then when checking the pids, i see:
root@c872a302032a:/# ps -elf
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S root 1 0 0 80 0 - 1160 - 17:54 ? 00:00:00 sh -c . /expandEnvSecrets.sh && java $JAVA_OPTS -jar /application.jar
4 S root 17 1 99 80 0 - 1712195 - 17:54 ? 00:00:20 java -jar /application.jar
4 S root 151 0 0 80 0 - 4630 - 17:54 pts/0 00:00:00 bash
4 R root 161 151 0 80 0 - 8604 - 17:54 pts/0 00:00:00 ps -elf
Interesting. That’s probably worth a sidebar in the guide. You can PR it if you want (I won’t get to it straight away anyway).
In the "The Entry Point" section it is suggested to wrap the launching of the application in
sh
to be able to pass env vars to the launch command. E.g.ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar"]
From what I have read elsewhere this is a very bad idea, as the java process that is spawned will not receive a SIGTERM when docker begins to stop the container (SIGTERM is sent to PID 1 which is sh in this case, which does not forward the SIGTERM to child processes). The spring application will therefore simply have the plug pulled rather than allowing the shutdown hooks to kick in for the application to gracefully shut down.
It might be a good idea to either remove this suggestion, or put a big nasty warning next to it.
Incidentally, we are using
ENTRYPOINT ["java","-jar","/app.jar"]
and setting env varJAVA_TOOL_OPTIONS
instead ofJAVA_OPTS
, which seems to work fine as this env var is read automatically, although not sure if this has any detrimental impact yet)