I've noticed that many entrypoint.sh scripts for docker do something like this:
#!/bin/bash
set -e
... code ...
exec "$@"
What are the set -e
and the exec "$@"
for?
I've noticed that many entrypoint.sh scripts for docker do something like this:
#!/bin/bash
set -e
... code ...
exec "$@"
What are the set -e
and the exec "$@"
for?
set -e
- exit script if any command fails (non-zero value)exec "$@"
- will redirect input variables, see more hereset -e
sets a shell option to immediately exit if any command being run exits with a non-zero exit code. The script will return with the exit code of the failing command. From the bash man page:exec "$@"
is typically used to make the entrypoint a pass through that then runs the docker command. It will replace the current running shell with the command that"$@"
is pointing to. By default, that variable points to the command line arguments.If you have an image with an entrypoint pointing to entrypoint.sh, and you run your container as
docker run my_image server start
, that will translate to runningentrypoint.sh server start
in the container. At the exec lineentrypoint.sh
, the shell running as pid 1 will replace itself with the commandserver start
.This is critical for signal handling. Without using
exec
, theserver start
in the above example would run as another pid, and after it exits, you would return to your shell script. With a shell in pid 1, a SIGTERM will be ignored by default. That means the graceful stop signal thatdocker stop
sends to your container, would never be received by theserver
process. After 10 seconds (by default),docker stop
would give up on the graceful shutdown and send a SIGKILL that will force your app to exit, but with potential data loss or closed network connections, that app developers could have coded around if they received the signal. It also means your container will always take the 10 seconds to stop.Note that with shell commands like
shift
andset --
, you can change the value of"$@"
. E.g. here's a short part of a script that removes the/bin/sh -c "..."
from the command that can appear if you use docker's shell syntax forCMD
:It basically takes all the extra command line arguments and execs them as a command. The intention is basically "Do everything in this .sh script, then in the same shell run the command the user passes in on the command line".
See: