The only job of some containers is to keep running and people can exec into it and execute some commands.
Too keep the containers running, there are some ways to do this.
Infinity Sleep
At the end of entrypoint script, add an infinity sleep.
1 | while [ true ]; do |
or if the container’s OS supports,
1 | sleep infinity |
Throws away anything from /dev/null
1 | tail -f /dev/null |
The only problem is that neither of those commands handles SIGINT properly, so they won’t respond to stop
in a timely manner.
Here’s how you get the container to stop gracefully. In your entrypoint script:
1 |
|
The tail
goes at the end of your script, the trap
can go anywhere, but usually is one of the first lines.
Elaborate on the solution:
trap : TERM INT
: basically means “catch”(or trap) all TERM and INT signals(both are commands that gracefully kill the process). The :
in the trap is treated as true
in all POSIX shells. It’s there in case something else, another script or program, set up its own trap before this one. The empty trap clears out the other old ones and ensures the signals belong to this script.
After it ensures the signals aren’t going to trigger something else, the tail
just there so we can use wait
, which is a small program that is known to handle signals well and generally does the right thing as its signal handling behavior is defined in POSIX: Linux Programmer’s Manual - WAIT(2).
tail
will never finish as it’s following an empty device that never returns anything throws away anything it gets (/dev/null
).
This script is just trying to account for unclean environments and be POSIX compatible.
While loop
Because tail
will still causes some file operations from time to time. So can use the following one-liner to keep a container alive.1
2# Ah, ha, ha, ha, stayin' alive...
while :; do :; done & kill -STOP $! && wait $!