2

How does ENTRYPOINT to a Docker container work exactly? I have a base docker image which has an ENTRYPOINT script and I am building another image on top of that which has one more ENTRYPOINT script.

When I run the image will both the ENTRYPOINT scripts run?

5

If the parent image contains a line:

ENTRYPOINT ["/entrypoint-parent.sh"]

and you want to add the following to your child image:

ENTRYPOINT ["/entrypoint-child.sh"]

Then the value of ENTRYPOINT in the resulting image is replaced with /entrypoint-child.sh, in other words, there is only a single value for ENTRYPOINT. Docker will only call a single process to start your container, though that process can spawn child processes. There are a couple techniques to extend entrypoints.

Option A: Call your entrypoint, and then run the parent entrypoint at the end, e.g. /entrypoint-child.sh could look like:

#!/bin/sh

echo Running child entrypoint initialization steps here
# ...

exec /entrypoint-parent.sh "$@"

The exec part is important, it replaces the current shell by the /entrypoint-parent.sh shell or process, which removes issues with signal handling. The result is you run the first bit of initialization in the child entrypoint, and then delegate to the original parent entrypoint. This does require that you keep track of the name of the parent entrypoint, would could change between versions of your base image.

Option B: Run the parent entrypoint in the background. This is less than ideal since you will no longer have error handling on the parent process unless you take some extra steps. At the simplest, this looks like the following in your /entrypoint-child.sh:

#!/bin/sh

# other initialization steps

/entrypoint-parent.sh "$@" &

# potentially wait for parent to be running by polling

# run something new in the foreground, that may depend on parent processes
exec /child-process.bin

Note, the "$@" notation I keep using is passing through the value of CMD as arguments to the parent entrypoint.

Option C: Switch to a tool like supervisord. I'm not a huge fan of this since it implies running multiple daemons inside your container, and you are usually best to split that into multiple containers. You need to decide what the proper response is when a single child process keeps failing.

Option D: Similar to Options A and B, I often create a directory of entrypoint scripts that can be extended at different levels of the image build. The entrypoint itself is unchanged, I just add new files into a directory that gets called sequentially based on the filename. In my scenarios, these scripts are all run in the foreground, and I exec the CMD at the end. You can see an example of this in my base image repo, in particular the entrypoint.d directory and bin/entrypointd.sh script which includes the section:

# ...

for ep in /etc/entrypoint.d/*; do
  ext="${ep##*.}"
  if [ "${ext}" = "env" -a -f "${ep}" ]; then
    # source files ending in ".env"
    echo "Sourcing: ${ep}"
    set -a && . "${ep}" && set +a
  elif [ "${ext}" = "sh" -a -x "${ep}" ]; then
    # run scripts ending in ".sh"
    echo "Running: ${ep}"
    "${ep}"
  fi
done

# ...

# run command with exec to pass control
echo "Running CMD: $@"
exec "$@"
| improve this answer | |
1

No, there is a single entry point, so your script will replace the one defined in the parent image. But your script can call(*) or borrow code from the script used by the parent image.

(*) Only if this the last step of course. Note that in a well-designed container, you should exec the last command of your script, so that this becomes the container's main process. If you fail to do so, signals sent to terminate the container gracefully (SIGINT/SIGTERM) will be sent to your script (which won't do anything with them) instead of being sent to the container "real" process. Thois will 1) make the container slow to stop and 2) will prevent graceful exit: docker stop will send a SIGTERM, and if the container doesn't terminate in a timely manner (10 seconds) it will use a SIGKILL. If you exec a script which itself exec's a command then the command will become the main process and everything will be fine, too.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.