An init process in the container, or PID 1 ignores your signals

PID 1 in Linux does not get default signal handlers, so a shell script as the entrypoint ignores SIGTERM entirely — and docker stop waits ten seconds and then kills it.

# the symptom
$ time docker-compose stop php
real    0m10.412s              # the grace period, every time

# the fix in a script: exec, so the real process becomes PID 1
# exec "$@"

# and for anything that forks children:
$ docker run --init app        # tini as PID 1, reaps zombies too

The exec is the one-character fix for the common case and it is easy to omit — a script ending with php-fpm -F leaves the shell as PID 1 forever. --init covers the harder case where the process legitimately forks and nothing is reaping the children, which shows up as a container slowly accumulating zombie processes over days. Ten seconds per container per deploy adds up quickly on a stack of seven.