Docker-nginx: Define default stop signal in Dockerfile or update Documentation

Created on 21 Oct 2015  路  7Comments  路  Source: nginxinc/docker-nginx

The upcoming docker 1.9 release will add support for defining the default stop signal sent by docker stop:

  1. At run time through the --stop-signal option added to docker run
  2. At build time through the STOP keyword in the Dockerfile syntax.

Prior to this addition, alternative signals had to be sent using docker kill -s with the desired signal. (I feel this information should be added to the docker hub documentation for the official nginx images) considering nginx expects SIGQUIT for graceful shut down while docker stop sends SIGTERM by default (causing a fast shutdown by default and not a gracefull shutdown).

As detailed in the nginx documentation here:

| Signal | master process action |
| --- | --- |
| TERM, INT | fast shutdown |
| QUIT | graceful shutdown |
| HUP | changing configuration, keeping up with a changed time zone (only for FreeBSD and Linux), starting new worker processes with a new configuration, graceful shutdown of old worker processes |
| USR1 | re-opening log files |
| USR2 | upgrading an executable file |
| WINCH | graceful shutdown of worker processes |

enhancement

Most helpful comment

@bluefoxicy does this only effect nginx when it is listening on a UNIX domain socket...

I don't think that this would be nearly as common a use-case as listening over TCP for most dockerised setups ...

It would be quite beneficial e.g. with the default setup people will end up using nginx for in Kubernetes to use SIGQUIT...

Kubernetes simultaneously stops sending new requests and calls stop on the container... if STOPSIGNAL is SIGTERM then there is a chance that in-flight requests would be dropped...
or this is my understanding anyway ... perhaps I am wrong and SIGTERM doesn't drop in-flight requests?

There are a few ways that people using Kubernetes could work around this ...

  • add a preStop hook that sleeps for some number of seconds, thus waiting for connections to drain...
  • Build a container like:
FROM nginx
STOPSIGNAL SIGQUIT

IDK but it sounds like usecases where Nginx listens to sockets are more relevant to setups on single servers ... use in Docker -> Clustered Setups seem more likely to using TCP ...

It would be nice for Nginx to be deployable to Kubernetes (and similar) out of the box without dropping connections or needing some special config...

Some ideas:

  • Perhaps there could be a variant of the image offering optimisations for use-cases that require listening to sockets ...
  • If this container ships with STOPSIGNAL SIGQUIT perhaps there should also be a default value for worker_shutdown_timeout

All 7 comments

I should probably make a pull request with updated documentation in the appropriate place:
https://github.com/docker-library/docs/tree/master/nginx

The STOP keyword is now STOPSIGNAL. Why is this inappropriate in nginx Dockerfile, or did I miss anything?

@so0k which one do you feel is the most appropriate to define as a STOPSIGNAL? I still think TERM, since graceful will not ensure workers will exit, e.g. in case of long-lived connections, such as websocket.

which one do you feel is the most appropriate to define as a STOPSIGNAL? I still think TERM, since graceful will not ensure workers will exit, e.g. in case of long-lived connections, such as websocket.

In that case, it always can fallback to timeout ensurance, I think the default behavior should be try the best not to inturupt requests.

Done starting with nginx:1.13.0 / mainline and nginx:1.12.0 / stable - default stop signal is now QUIT. Please use http://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout to set a timeout if you wish.

The only reason people use SIGQUIT is the name says "graceful".

A graceful shutdown closes in an inconsistent state if you have any Unix domain sockets in your configuration. Since this update, nginx docker containers listening on Unix domain sockets have been incapable of restarting without manual intervention because they leave behind Unix domain sockets nginx creates on start, causing nginx to fail to start.

This is why Ubuntu and Debian specifically remove the SIGSTOP directive from the init script and change to SIGTERM.

Never do this again.

@bluefoxicy does this only effect nginx when it is listening on a UNIX domain socket...

I don't think that this would be nearly as common a use-case as listening over TCP for most dockerised setups ...

It would be quite beneficial e.g. with the default setup people will end up using nginx for in Kubernetes to use SIGQUIT...

Kubernetes simultaneously stops sending new requests and calls stop on the container... if STOPSIGNAL is SIGTERM then there is a chance that in-flight requests would be dropped...
or this is my understanding anyway ... perhaps I am wrong and SIGTERM doesn't drop in-flight requests?

There are a few ways that people using Kubernetes could work around this ...

  • add a preStop hook that sleeps for some number of seconds, thus waiting for connections to drain...
  • Build a container like:
FROM nginx
STOPSIGNAL SIGQUIT

IDK but it sounds like usecases where Nginx listens to sockets are more relevant to setups on single servers ... use in Docker -> Clustered Setups seem more likely to using TCP ...

It would be nice for Nginx to be deployable to Kubernetes (and similar) out of the box without dropping connections or needing some special config...

Some ideas:

  • Perhaps there could be a variant of the image offering optimisations for use-cases that require listening to sockets ...
  • If this container ships with STOPSIGNAL SIGQUIT perhaps there should also be a default value for worker_shutdown_timeout
Was this page helpful?
0 / 5 - 0 ratings

Related issues

lrhazi picture lrhazi  路  3Comments

hasancansaral picture hasancansaral  路  6Comments

HeyRobb picture HeyRobb  路  5Comments

a-shink picture a-shink  路  3Comments

jsdevel picture jsdevel  路  5Comments