0

I have a Flask application which I want to shutdown gracefully. Currently, it is ignoring the SIGTERM signal from docker, which leads to a SIGKILL signal a few seconds later (after stop-grace-period).

I know I can handle the signal using the following code:

import signal

def signal_handler(signum, frame):
    logging.info(f'Signal handler called with signal {signum}')
    if signum in [signal.SIGINT, signal.SIGTERM]:
        logging.info("Attempting to shutdown gracefully")
        # ...Missing shutdown code...

signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

But I am missing the code to actually shutdown the app. I tried another answer:

shutdown_server = request.environ.get('werkzeug.server.shutdown')
if shutdown_server is not None:
   shutdown_server()

However I get the exception:

  File "/app/flask_app/server.py", line 19, in signal_handler
    shutdown_func = request.environ.get('werkzeug.server.shutdown')
  File "/root/.cache/pypoetry/virtualenvs/flask-app-9TtSrW0h-py3.9/lib/python3.9/site-packages/werkzeug/local.py", line 432, in __get__
    obj = instance._get_current_object()
  File "/root/.cache/pypoetry/virtualenvs/flask-app-9TtSrW0h-py3.9/lib/python3.9/site-packages/werkzeug/local.py", line 554, in _get_current_object
    return self.__local()  # type: ignore
  File "/root/.cache/pypoetry/virtualenvs/flask-app-9TtSrW0h-py3.9/lib/python3.9/site-packages/flask/globals.py", line 33, in _lookup_req_object
    raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.

Apparently, that only works if I am within the context of a request. I don't want to add a /shutdown endpoint just for this.

For context, I am defining my app inside a create_app factory, and starting it with: poetry run flask run. Inside my Dockerfile I'm using CMD ["poetry", "run", "flask", "run"]

How can I gracefully handle the SIGTERM signal and shutdown the flask application?

driangle
  • 11,601
  • 5
  • 47
  • 54

0 Answers0