Keep A Container Running

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.

Issue #1926: Keep a container running in compose

Infinity Sleep

At the end of entrypoint script, add an infinity sleep.

1
2
3
while [ true ]; do
sleep 3600;
done

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
2
3
#!/bin/sh
trap : TERM INT
tail -f /dev/null & wait

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 $!