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.