Given is a microservice that after some time needs to quit itself. This is no error condition but (in that case) normal behavior. After exiting it should be automatically restarted.
So currently I have a script run_app.sh
:
#!/usr/bin/env bash
while true; do ./app ; done
And in the Dockerfile
(inheriting FROM ubuntu:16.04
) I run it like this:
CMD ["./run_app.sh"]
It "works" but since app
does not have PID 1, it does not receive SIGTERM etc. coming from Kubernetes, which is needed for a graceful shutdown during rolling updates etc.
Using while true; do exec ./app ; done
in run_app.sh
does not solve the problem since the loop no longer exists when app
finished and no restart is performed.
How can I restart the app automatically inside the container without restarting the container / pod every time it quits, but still have the advantages of PID 1?
Well, your loop does restart your app, so this is not your problem. Your problem is that the signal sent to the docker container is not propagated into the container. Docker just isn't (AFAIK) not meant to be used like this, so it doesn't propagate signals to its app.
You have two ways of handling this:
You can teach the signal sender (Kubernetes or whatever) to instead of sending a signal to the Docker container do something more elaborate to get the information to the app inside the container. I guess this is not easy (if possible at all).
You can migrate the looping shell script outside of the container and let Kubernetes (or whatever) run this script instead. Within the loop you then can start the Docker container with your app inside. In this case you will need to catch the SIGTERM in the outside looping shell script (help trap
) and either send a SIGTERM to the Docker container directly or to the app within the Docker container (using Docker exec
or similar).