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>
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.
The original value of image ENTRYPOINT can be found in its Dockerfile or get overrided by compose.yaml.
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
CMDis defined from the base image, settingENTRYPOINTwill resetCMDto an empty value. In this scenario,CMDmust 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.
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.
$@ 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?