Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIGTERM not working with exec command in the entrypoint script #195

Closed
kgrv-me opened this issue May 10, 2022 · 4 comments
Closed

SIGTERM not working with exec command in the entrypoint script #195

kgrv-me opened this issue May 10, 2022 · 4 comments

Comments

@kgrv-me
Copy link

kgrv-me commented May 10, 2022

Hi guys,

I have ENTRYPOINT [ "/sbin/tini", "--", "entrypoint.sh" ] in the Dockerfile.

In entrypoint.sh, I have just one line exec bash; in this case, using stop from Docker Desktop results in SIGKILL (137) instead of SIGTERM (143) with long shutdown.
If I changed exec bash to just bash, SIGTERM worked properly with immediate shutdown.
Interestingly, using exec fish works properly as well.

From researching, exec seems to be recommended to avoid improper signal handling/forwarding by replacing the middle man. However, in this case, it seems to be doing the opposite for bash. I'm assuming exec bash should work just like bash would when stopping the container.

Can someone help clarify this for me? What am I missing that exec bash doesn't work when I'm trying to stop the container?
Thank you.

@yosifkit
Copy link

I'm assuming that you are running an interactive container similar to: docker run it --rm custom-image.

When you just run bash the process tree in the container looks like this: tini -> sh entrypoint.sh -> bash
But with exec bash it looks like this: tini -> bash. tini forwards the signal to its child, but that process may or may not repeat it to its own children.

Since the entrypoint script being run by sh does not define a signal handler, then it gets the default when a running script and exits when it gets a SIGTERM, and thus its child bash is also killed when the container exits. But an interactive bash shell does not, which is why it doesn't die until it gets the later SIGKILL from docker stop.

When Bash is interactive, in the absence of any traps, it ignores SIGTERM

-https://www.gnu.org/software/bash/manual/html_node/Signals.html

@kgrv-me
Copy link
Author

kgrv-me commented May 10, 2022

I'm assuming that you are running an interactive container similar to: docker run it --rm custom-image.

When you just run bash the process tree in the container looks like this: tini -> sh entrypoint.sh -> bash But with exec bash it looks like this: tini -> bash. tini forwards the signal to its child, but that process may or may not repeat it to its own children.

Since the entrypoint script being run by sh does not define a signal handler, then it gets the default when a running script and exits when it gets a SIGTERM, and thus its child bash is also killed when the container exits. But an interactive bash shell does not, which is why it doesn't die until it gets the later SIGKILL from docker stop.

When Bash is interactive, in the absence of any traps, it ignores SIGTERM
-https://www.gnu.org/software/bash/manual/html_node/Signals.html

Ahhh, I assumed that bash handles signals the same both in interactive and script forms, which led me into a rabbit hole.

Is STOPSIGNAL SIGKILL in Dockerfile the only remedy to be able to utilize exec bash then? Or is there another proper/elogant way of archiving this?

My thinking is that I wouldn't want entrypoint.sh process to dangle after invoking interactive bash so doing tini -> bash looks appropriated. Is using exec bash not recommended in this case? Or am I heading into a right direction, just short of my goal?

Thank you very much for your reply!

@krallin
Copy link
Owner

krallin commented May 10, 2022 via email

@kgrv-me
Copy link
Author

kgrv-me commented May 11, 2022

You could experiment with the -g flag, which would have Tini send signals to the process group of your children, which I think in non-interactive bash would be the same as bash itself. If you can’t use exec, it might be worth a try.

On Tue, 10 May 2022 at 19:46, kgrv-me @.> wrote: I'm assuming that you are running an interactive container similar to: docker run it --rm custom-image. When you just run bash the process tree in the container looks like this: tini -> sh entrypoint.sh -> bash But with exec bash it looks like this: tini -> bash. tini forwards the signal to its child, but that process may or may not repeat it to its own children. Since the entrypoint script being run by sh does not define a signal handler, then it gets the default when a running script and exits when it gets a SIGTERM, and thus its child bash is also killed when the container exits. But an interactive bash shell does not, which is why it doesn't die until it gets the later SIGKILL from docker stop. When Bash is interactive, in the absence of any traps, it ignores SIGTERM -https://www.gnu.org/software/bash/manual/html_node/Signals.html Ahhh, I assumed that bash handles signals the same both in interactive and script forms, which led me into a rabbit hole. Is STOPSIGNAL SIGKILL in Dockerfile the only remedy to be able to utilize exec bash then? Or is there another proper/elogant way of archiving this? My thinking is that I wouldn't want entrypoint.sh process to dangle after invoking interactive bash so doing tini -> bash looks appropriated. Is using exec bash not recommended in this case? Or am I heading into a right direction, just short of my goal? Thank you very much for your reply! — Reply to this email directly, view it on GitHub <#195 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANIHVX7OK4ZP3GX2HCLMDLVJKVI5ANCNFSM5VSFEBCA . You are receiving this because you are subscribed to this thread.Message ID: @.>

I tried that already and it didn't work due to the nature of interactive bash (great explanation and link from @yosifkit).
I have decided to go with STOPSIGNAL SIGHUP in the Dockerfile such that interactive bash will forward the signal to all jobs before exiting.

Thank you all for your help, much appreciated it!

@kgrv-me kgrv-me closed this as completed May 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants