'Speed up docker-compose shutdown
When I set up my application to run via docker-compose up
, it takes several seconds to stop on ctrl+c. However, if I run docker kill ...
, the container stops very quickly. Is there anything I can do to speed up container shutdown when killed via ctrl+c within docker-compose up
?
In particular, what does it actually mean when docker-compose says it is "gracefully stopping "? Is docker-compose trying some shutdown protocol and then killing my container only after a timeout?
Solution 1:[1]
what does it actually mean when docker-compose says it is "gracefully stopping "?
Basically when you do Ctrl+C you are sending a SIGINT (2) signal to the application that runs in the foreground. Most of the time, the semantics of this signal is similar to the SIGTERM (15) signal that is raised when doing docker-compose stop
or more basically docker stop
if you are focusing on a single-container application.
Is docker-compose trying some shutdown protocol and then killing my container only after a timeout?
Yes, the idea is that the running application can catch the SIGINT and SIGTERM signal and perform some cleanup operation before exiting.
On the contrary, the SIGKILL (9) signal (raised by docker kill
for example) causes the process to terminate immediately.
You might be interested in this related SO answer where I give a toy example of entrypoint bash script that "catches" SIGINT and SIGTERM signals (but not SIGKILL, of course).
Is there anything I can do to speed up container shutdown when killed via ctrl+c within docker-compose up?
I'd say the time spent by your containers to exit when you do docker stop
or so strongly depends on the implementation of the corresponding images.
At first sight, you might modify (e.g., shorten) the time offered to the containers to gracefully stop:
but this would certainly not be a proper solution.
Actually, there are two typical pitfalls when one comes to rely on an entrypoint bash script:
Use a bash script as a wrapper to finally call another program, but forget to use the
exec
builtin.
? The recommended practice consists in prepending the last command of a bash entrypoint withexec
(for example, see this line fromentrypointd.sh
insudo-bmitch/docker-base
).When the bash script itself should not terminate immediately, one could forget to take care of trapping the signals (including SIGINT and SIGTERM) and behave accordingly, which can also be the cause of the issue you observe. This is related to the so-called PID 1 zombie reaping problem.
? To workaround this, you may want to run your image with thedocker run
flag--init
, or add thedocker-compose.yml
parameterinit
(related SO Q.)
Solution 2:[2]
If you find yourself restarting containers frequently and some don't gracefully exit or have long exit times (ie. you want more than 10s before it's killed), you can now do this per-service/container with stop_grace_period
stop_grace_period
specifies how long the Compose implementation MUST wait when attempting to stop a container if it doesn’t handleSIGTERM
(or whichever stop signal has been specified withstop_signal
), before sending SIGKILL. Specified as a duration.
For example
services:
service_A:
...
stop_grace_period: 1s # SIGKILL after 1s
service_B:
...
stop_grace_period: 5m30s # wait a long time before SIGKILL
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | ti7 |