I have the very same problem, has anyone figured this one out yet?
queue:work or queue:listen for Docker?
Hello,
I am launching our stack using the following images in a Kubernetes cluster on Google Container Engine:
- php-fpm
- nginx
- beanstalkd
- beanstalkd-console
- redis
Now the question I have is for processing the queue. Since we are using Kubernetes we will be using the Deployment rollout pattern to upgrade our application containers once the app has been "dockerized":
- nginx
- php-fpm
- queue
In the queue container, I'm trying to figure out if I should use queue:work and just set the RestartPolicy=Always so that way when a job is finished processing the container dies and is replaced by another one. Or is there a better way to run queue:work --daemon (or queue:listen) and send some sort of shutdown command to the container so it finishes processing it's workload and then stops it's process?
Cheers, Andrew
Hey guys,
I should have posted an update about this when I found a solution; but totally forgot.
We ended up going with k8s Deployments which doing a rolling update of containers. When using this implementation you have the PreStop Lifecycle hook you can leverage.
https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods
For this we wrote a script that runs the following:
#!/bin/bash
cd /app
php artisan queue:stop
while [ `ps aux | grep "queue:work" | wc -l` -gt 1 ];
do
echo "Waiting for the queue to shutdown...";
sleep 1
done
exit 0
This sends the shutdown signal to the queue worker. Then checks every second to see if the worker has been shutdown. The -gt 1 check is there because ps aux | grep always returns 1 result. You could modify this to exclude the grep, but why? This works.
Then once the queue:work process is dead, the script exits with a zero status code to signal a success.
This works because the PreStop lifecycle hook is blocking (synchronous). So the container will not shut down before that script exits. This allows the current job to be processed, and finished, before shutting the container down and replacing it with the updated container running the new app code.
To configure this within your Deployment file, you would do the following:
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: app
image: app:{version}
ports:
- containerPort: 80
lifecycle:
preStop:
exec:
command: ["/app/bin/stopQueue.sh"]
Please or to participate in this conversation.