Docker (and, therefore, Kubernetes) send SIGTERM as the default signal to stop containers. Docker will then wait 10 seconds before sending SIGKILL, Kubernetes will wait 30 seconds. They expect containers to exit gracefully within this grace period:
When you issue a docker stop command Docker will first ask nicely for the process to stop and if it doesn't comply within 10 seconds it will forcibly kill it. If you've ever issued a docker stop and had to wait 10 seconds for the command to return you've seen this in action
From: https://www.ctl.io/developers/blog/post/gracefully-stopping-docker-containers/
It鈥檚 important that your application handle termination gracefully so that there is minimal impact on the end user and the time-to-recovery is as fast as possible!
In practice, this means your application needs to handle the SIGTERM message and begin shutting down when it receives it. This means saving all data that needs to be saved, closing down network connections, finishing any work that is left, and other similar tasks.
From: https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-terminating-with-grace
However, this is not what nginx does:
TERM, INT fast shutdown
QUIT graceful shutdown
From: http://nginx.org/en/docs/control.html
The Dockerfiles in this project use STOPSIGNAL SIGTERM (which actually isn't necessary since this is the default).
What this means in practice is that when Docker or Kubernetes decide to stop a container, nginx will die immediately, closing any connections straight away:
$ curl localhost
curl: (52) Empty reply from server
It would be much healthier, and comply with the ethos of both Docker and Kubernetes if instead the nginx image made an effort to close all connections before shutting down. This can be achieved nicely with:
STOPSIGNAL SIGQUIT
I've verified this behaviour locally with this Dockerfile.
We discussed that in https://github.com/nginxinc/docker-nginx/issues/167 - can you check if dangling sockets are still an issue with your approach?
Okay, interesting. We don't use any unix sockets, so it's not an issue for us.
But more generally, this SIGTERM behaviour seems definitely undesirable to me. Given how prevalent nginx is, and how prevalent its usage in e.g. Kubernetes is, the default docker image should really be able to shut down gracefully without causing broken connections.
It seems to me that the correct signal to send is SIGQUIT and the issue with unix signals is a bug that should be fixed. Is the nginx project aware of the issue?
(Either that or nginx should change its behaviour on SIGTERM to be more graceful)
nginx is aware of the issue, see https://trac.nginx.org/nginx/ticket/753 for more details.
Now that https://trac.nginx.org/nginx/ticket/753 is fixed, we can try moving to SIGQUIT.
The fix was released in 1.19.1. Can this be implemented then?
Most helpful comment
Now that https://trac.nginx.org/nginx/ticket/753 is fixed, we can try moving to SIGQUIT.