I want to run a background queue working in my docker image:
php artisan queue:work --daemon --sleep=1 --tries=3 &
Immediately after that it starts Apache httpd
running a PHP laravel
app. The laravel
app sends push notifications out to Redis. The background queue worker collects the messages from Redis and sends them via a push service.
That works and logs out every second. In case the background command crashes I would like it to restart. According to this answer https://unix.stackexchange.com/a/223780/72040 I can run a command infinitely in the background with something like:
while true; do php $QUEUE_WORK; done &
To test this I ran my container with docker run
then did docker exec -it
to login and see:
UID PID PPID C STIME TTY TIME CMD
100000 1 0 0 19:55 ? 00:00:00 httpd -D FOREGROUND
100000 21 1 0 19:55 ? 00:00:00 /bin/sh -e /tmp/scripts/run
100000 22 21 1 19:55 ? 00:00:01 php artisan queue:work --sleep=1 --tries=3
100000 43 1 0 19:55 ? 00:00:00 /usr/bin/cat
100000 50 1 0 19:55 ? 00:00:00 /usr/bin/cat
100000 51 1 0 19:55 ? 00:00:00 /usr/bin/cat
100000 52 1 0 19:55 ? 00:00:00 /usr/bin/cat
100000 53 1 0 19:55 ? 00:00:00 httpd -D FOREGROUND
...
100000 130 0 1 19:57 pts/0 00:00:00 /bin/bash
100000 144 130 0 19:57 pts/0 00:00:00 ps -efww
I then run kill 22
see output on the docker run
of:
/tmp/scripts/run: line 10: 22 Killed php $QUEUE_WORK
The loop doesn't keep the process up. I have double checked that the loop is the code being run in the image. If I have the loop run a ”echo x: sleep 1” it runs okay.
Why doesn't the loop replace the command when I kill it?
NOTE: The application is deployed as multiple pods on Kubernetes with monitoring and automated restarts if the httpd
health check URL returns an error or time-out.
I don't want to deploy the queue workers as a separate pod or as a sidecar container I want to run it as a background process in the httpd
container so that it shares the application code with httpd
with zero config.
I am not interested in running process monitors or other tools or technology to ”keep alive”.
My question is why does the Bash loop exit on kill
of the process it is running?
Best Answer
Setup
I set up the following
Dockerfile
:Setup a script,
run.sh
:Built it:
Example
Then started it up:
Then it runs repeatedly showing:
Now when I watch it I can see that it's staying up, in spite of the
sleep
commands eventually "dying":From above we can see that this container has been up in excess of 1 minute. Here's what the
ps auxf
looks like of the inside of the container:Now if we kill the background
sleep 15
like so:And run another
docker ps
:We can see that the while loop that's guarding our background
sleep 15
process has done its job and restarted anothersleep 15
.