Compose: Flask apps cannot be gracefully stopped

Created on 29 Nov 2016  路  4Comments  路  Source: docker/compose

Every time I run Flask apps in a docker-compose configuration, they always take awhile to stop. I tried testing this cloning this repository, navigating to the cloned directory and running docker-compose up, and then pressing Ctrl-C once the containers are running. Here is the stdout I see:

Recreating dockerflasktest_greetings_1
Recreating dockerflasktest_mathmachine_1
Attaching to dockerflasktest_greetings_1, dockerflasktest_mathmachine_1
greetings_1   |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
mathmachine_1 |  * Running on http://0.0.0.0:5001/ (Press CTRL+C to quit)
^CGracefully stopping... (press Ctrl+C again to force)
Stopping dockerflasktest_mathmachine_1 ... done
Stopping dockerflasktest_greetings_1 ... done
dockerflasktest_mathmachine_1 exited with code 137
dockerflasktest_greetings_1 exited with code 137

After doing some research, I found out that "exited with code 137" meant that the containers had to be stopped using SIGKILL. When I tried running the containers individually (e.g. docker-compose run greetings or docker-compose run mathmachine), they were able to stop gracefully, so I think that the problem lies in docker-compose. Has anyone else encountered this issue?

If it's relevant, I ran this on an Ubuntu 16.04 VM.

Most helpful comment

Not to reopen a dead issue, but for future searchers.

Flask will stop gracefully on SIGINT (Ctrl-C).
docker-compose tries to stop processes using SIGTERM by default, then sends SIGKILL after a delay if the process doesn't stop.
The default docker-compose signal can be overridden using:

stop_signal: SIGINT

Hope that helps!

All 4 comments

What does your Dockerfile look like? If you're setting the CMD or ENTRYPOINT as a string (the "shell form") and not a list of strings (the "exec form"), it'll be wrapped in sh, causing signals to be ignored. See the CMD reference.

My Dockerfiles end with the line CMD ["python", "/src/app.py"], so I assumed that I was using the exec form. I tried replacing that CMD with the below two lines, but the problem still happens.

ENTRYPOINT ["python"]
CMD ["/src/app.py"]

I've also tried replacing CMD in the original line with ENTRYPOINT, but again, the problem still happens.

I resolved the issue by adding Gunicorn as a Python dependency and running my Flask app through Gunicorn instead of through Python. So if I wanted to run my Flask app on port 5000, my CMD line would be:

CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]

When I press Ctrl-C, the apps stopped gracefully.

Not to reopen a dead issue, but for future searchers.

Flask will stop gracefully on SIGINT (Ctrl-C).
docker-compose tries to stop processes using SIGTERM by default, then sends SIGKILL after a delay if the process doesn't stop.
The default docker-compose signal can be overridden using:

stop_signal: SIGINT

Hope that helps!

Was this page helpful?
0 / 5 - 0 ratings