Home > Enterprise >  Peaceful "docker stop" when running exec in background w/ docker container via shell scrip
Peaceful "docker stop" when running exec in background w/ docker container via shell scrip

Time:06-09

I have a Docker container running a UWSGI server that's serving an API built in Python using Flask, which has the command ENTRYPOINT ["./startapi.sh"] to start up the server when the container is built. The container uses nginx as a reverse proxy to handle requests and serve them to the API inside the UWSGI instance.

startapi.sh contains the following:

#!/bin/bash
service nginx start
exec uwsgi --ini uwsgi.ini &
while :; do nginx -s reload; sleep 6h; done

However, when I try to docker stop the container, it waits the full 10s before sending SIGKILL to the container because PID 1 inside the container is /bin/bash ./startapi.sh. I know why--because the SIGTERM that docker stop sends doesn't reach the UWSGI instance, as it is not PID 1.

I know how to resolve that--just remove the & from the end of exec uwsgi in startapi.sh--but then the while loop won't run because it follows the exec uwsgi command (at least, I don't see the loop when I run docker exec -it container.name ps auxww from the host). Swapping the two lines (putting the while loop before the exec uwsgi) will properly run the sleep command to reload nginx, but will fail to run exec uwsgi and therefore not launch the API.

My dilemma, thus, is this--I want PID 1 in my container to be uwsgi --ini uwsgi.ini so that docker stop gracefully stops the UWSGI server (and yes, I do have hook-master-start = unix_signal:15 gracefully_kill_them_all in my uwsgi.ini per a UWSGI GitHub issue, so it should comply with docker stop SIGTERM), but I also want to be able to reload nginx automatically every 6hrs via the while loop/sleep one-liner.

Is there something I can do to achieve that?

CodePudding user response:

So swap them. Literally. Run the loop in the background.

#!/bin/bash
service nginx start
while :; do nginx -s reload; sleep 6h; done &
exec uwsgi --ini uwsgi.ini

But really, you should be running supervisord instead.

Also, consider inotifywait and executing nginx -s reload when the config changed.

  • Related