The Docker platform leverages Docker containers to enable IT operations teams and Developer teams to build, ship and run any application, anywhere. (from docker.com)
I’ve been working with Docker for 3 years now and seen some cases where an image has to perform some steps before booting the application(s). It’s usual to see that done with a bash script that doesn’t launch the application preceded by an exec
command. Let me explain:
– Create a start
bash script that check if the file /foo
exists, print a message about it and simulates an application with netcat:
#!/bin/sh if [[ -f /foo ]] then echo 'File found' else echo 'File not found!' fi nc -l 4000 -k
– Create a Dockerfile that will add the start
script and launch it:
FROM alpine ADD start /start RUN chmod +x /start CMD ./start
– Build, run and test it:
$ docker build -t test-pid . $ docker run -it -d --name t-pid test-pid # Now let's run a shell to access the container: $ docker exec -it t-pid sh / # ps PID USER TIME COMMAND 1 root 0:00 /bin/sh -c ./start 5 root 0:00 {start} /bin/sh ./start 6 root 0:00 nc -l 4000 -k 7 root 0:00 sh 11 root 0:00 ps
You’ve noticed that start
script is the one that has PID 1 and that’s bad! Why is it bad? Because start
script can’t leverage signals, for example: SIGTERM
(docker stop) !
$ # Stop the container $ docker stop t-pid && docker rm t-pid $ # You will notice that it will take $ # 10 seconds to stop: https://github.com/docker/docker/issues/3766 $ # That's the default timeout for docker stop. $ # If the container wasn't able to deal with the SIGTERM, the force kill it.
– Change the above Dockerfile
and start
script to:
FROM alpine ADD start /start RUN chmod +x /start CMD exec ./start
#!/bin/sh if [[ -f /foo ]] then echo 'File found' else echo 'File not found!' fi exec nc -l 4000 -k
– Build, run and test it:
$ docker build -t test-pid-ok . $ docker run -it -d --name t-pid test-pid-ok # Now let's run a shell to access the container: $ docker exec -it t-pid sh / # ps PID USER TIME COMMAND 1 root 0:00 nc -l 4000 -k 5 root 0:00 sh 9 root 0:00 ps / # # Yay!! / # exit $ # Stop the container and see that it stops immediately! $ docker stop t-pid && docker rm t-pid