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?