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
CMD
is defined from the base image, settingENTRYPOINT
will resetCMD
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.
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?