Will the application run as PID 1 and will signals

2019-02-28 14:25发布

It's good practice to start the service with

CMD ["/go/bin/myapp"]

instead of

CMD /go/bin/myapp

In the first way, SIGTERMs are caught by the applicaiton, while in the second way, they are caught by the underlying /bin/sh script, which does not forward them to the service. I learned this from https://forums.docker.com/t/docker-run-cannot-be-killed-with-ctrl-c/13108/2.

Now I am wondering if CMD ["..."] is completely equivalent to putting ... in an /entrypoint.sh script and calling CMD ["/entrypoint.sh"]? Will now child applications also be running as PID 1 and therefore receive all signals?

As a concrete example, I want to create a script with:

envsubst < /etc/nginx/conf.d/site.template > /etc/nginx/conf.d/default.conf
&&
nginx -g 'daemon off;'

And call CMD ["/entrypoint.sh"] at the end of my Dockerfile. Is this safe and will nginx run as PID 1 despite that there are multiple commands (envsubst and ngingx) in the script?

This matter confuses me and I am trying to figure out when and when not to use tini (https://github.com/krallin/tini).

2条回答
叼着烟拽天下
2楼-- · 2019-02-28 15:04

Here is my try to follow what also the MySQL 5.7 Dockerfile does... but with an Nginx image.

Dockerfile:

FROM nginx:latest
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh

ENTRYPOINT ["docker-entrypoint.sh"] 
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

docker-entrypoint.sh:

#!/bin/bash
set -e

echo "preparing..."

exec "$@"

The idea is to do anything needed as a preparation inside the docker-entrypoint.sh script and with exec "$@" you then pass the signals to the CMD. (This means that you will have to use envsubst < /etc/nginx/conf.d/site.template > /etc/nginx/conf.d/default.conf inside docker-entrypoint.sh)


Link of relevant example to Dockerfile docs: If you need to write a starter script for a single executable, you can ensure that the final executable receives the Unix signals by using exec and gosu commands...

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-02-28 15:14

Quoting the tini GitHub page:

If you are using Docker 1.13 or greater, Tini is included in Docker itself. This includes all versions of Docker CE. To enable Tini, just pass the --init flag to docker run.

Or you can you use minit. It runs /etc/minit/startup on container startup and /etc/minit/shutdown when a container is stopped. I usually use this piece of code as entrypoint:

#!/bin/sh

if [ $# -gt 0 ] ; then
        exec "$@"
else
        exec /sbin/minit
fi
查看更多
登录 后发表回答