79333020

Date: 2025-01-06 12:31:18
Score: 0.5
Natty:
Report link
COPY <<'DASH' /etc/rc.local
    set -x
    printenv
DASH

RUN chmod +x /etc/rc.local
ENTRYPOINT dash -xc '/etc/rc.local && <the original entrypoint> $1' "$@"
CMD <the original cmd>

Explain:

  1. The file /etc/rc.local is a historical filename for putting scripts that will be executed by pre-systemd-era-daemon SysV init during the system boot: https://unix.stackexchange.com/questions/49626/purpose-and-typical-usage-of-etc-rc-local.

    Another similar path for this purpose is /etc/init.d/*: https://unix.stackexchange.com/questions/3537/etc-rc-d-vs-etc-init-d.

    Here we just take this filename for convention as in docker container there's no init/systemd daemon by default and the ENTRYPOINT is the pid 1.

  2. The original value of image ENTRYPOINT can be found in its Dockerfile or get overrided by compose.yaml.

  3. And setting a new ENTRYPOINT will reset the original CMD to empty string: https://docs.docker.com/reference/dockerfile/#understand-how-cmd-and-entrypoint-interact

    If CMD is defined from the base image, setting ENTRYPOINT will reset CMD to an empty value. In this scenario, CMD must be defined in the current image to have a value.

    so we have to copy the value of CMD from the Dockerfile of original image or compose.yaml if get overrided in it.

  4. dash -xc 'echo $1' arg is a way to pass shell arguments into sh -c: https://unix.stackexchange.com/questions/144514/add-arguments-to-bash-c/144519#144519, and this example shall run echo arg that can be verified by set -x.

  5. $@ is the value of all shell arguments except the first one like $argv[0] or $0 which is the value being passed to execv.

    In the shell env of entrypoint when a container is created, its $@ will be the value of Dockerfile CMD: https://docs.docker.com/reference/dockerfile/#understand-how-cmd-and-entrypoint-interact, so we could pass the value CMD from outer shell into the inner that created by sh -c 'echo $1' "$@".

    Double-quoting it "$@" will prevent shell IFS= word splitting for passing the whole Dockerfile CMD as a single argument into $1 in sh -c

Taking the offical docker image php as a example: We can find its original ENTRYPOINT is docker-php-entrypoint and original CMD is php-fpm, so we should fill them with:

ENTRYPOINT dash -xc '/etc/rc.local && docker-php-entrypoint $1' "$@"
CMD php-fpm

If the order of executing script before or after the entrypoint get started is not important for you, also try the much simpler post-start lifecycle hook in Docker Compose: docker-compose, run a script after container has started?

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • Ends in question mark (2):
Posted by: n0099