Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ellisio's avatar

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

0 likes
3 replies
eduardoleoni's avatar

I have the very same problem, has anyone figured this one out yet?

AHMADH's avatar

I've the same problem as well over docker

ellisio's avatar
ellisio
OP
Best Answer
Level 2

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"]
2 likes

Please or to participate in this conversation.