Docker + Laravel队列:工作

时间:2018-02-20 11:57:05

标签: laravel docker lumen

我尝试在容器启动并运行后运行以下命令。

php artisan queue:work -n -q &

"&"是因为守护程序选项已弃用,后来从Laravel中删除。

然而,这完全破坏了我的容器启动。

CMD ["php", "artisan", "queue:work", "-n", "-q", "&"]

我应该如何以Docker方式执行此操作?

编辑:

使用docker-compose我将此行添加到我的docker-compose.yml文件

command: bash -c 'php artisan queue:work -n -q;'

容器已启动但未提供任何请求:S

使用此:

command: bash -c 'php artisan queue:work -n -q &; echo "runs"; tail -f /dev/null'

启动后容器停止

最终解决方案

所以最后我认为负责提供应用程序的服务器可能不应该是运行队列的服务器。

因此,我启动了同一个docker镜像的另一个实例,其唯一目的是运行artisan queue:work。

4 个答案:

答案 0 :(得分:4)

您无法在后台运行队列,否则容器将停止,因为命令已有效完成。删除&,它将保持活力。

但是,如果要在后台运行队列并且仍然能够连接到容器并访问shell,则可以执行tail -f /dev/null之类的操作作为保持容器运行的最终命令。

答案 1 :(得分:3)

queue:work命令在前台运行,所以你应该以那种方式运行它,这样容器就不会立即退出。

由于Laravel中的应用程序代码与将容器作为Web应用程序,队列或调度程序运行相同,因此我构建了一个可以在这些上下文中使用的映像。我使用带有环境变量的bash start脚本来定义容器角色,这就是我为队列工作容器运行的内容:

#!/bin/bash

# Defaults to an app server
role=${CONTAINER_ROLE:-app}

if [ "$role" = "queue" ]; then
    # Run queue
    php artisan queue:work --verbose --tries=3 --timeout=90
elif [ "$role" = "app" ]; then
    # Run the web application
    /usr/bin/caddy --agree=true --conf=/etc/Caddyfile
elif [ "$role" = "scheduler" ]; then
    while [ true ]
    do
      php artisan schedule:run --verbose --no-interaction &
      sleep 60
    done
else
    echo "Could not match the container role...."
    exit 1
fi

还要注意无限循环和睡眠组合以保持调度程序角色运行并在后台运行schedule:run命令以防止调度程序运行重叠(因为无论最后一个是否完成,它们都需要每分钟运行一次)

答案 2 :(得分:1)

如果您需要正常关闭队列,可以按照此步骤进行。

这摘自@ Paul RedmondLaravel News的文章,并扩展了他的docker-entrypoint文件,因此适合我的需要。经过大量测试后,我终于能够做到了。

您的队列服务的docker-compose.yml文件集stop_signal: SIGTERM中的第一件事。

  queue:
    image: laravel-www
    container_name: laravel-queue
    stop_signal: SIGTERM
    depends_on:
      - app
    volumes:
      - .:/var/www/html
    ...

接下来,在entrypoint.sh文件中,主要操作是使用exec命令运行queue:work。

#!/usr/bin/env bash

set -e

# Run our defined exec if args empty
if [ -z "$1" ]; then
    role=${CONTAINER_ROLE:-app}
    env=${APP_ENV:-production}

    if [ "$env" != "local" ]; then
        echo "Caching configuration..."
        (cd /var/www/html && php artisan cache:clear && php artisan config:clear && php artisan route:clear && php artisan view:clear)
        (cd /var/www/html && php artisan config:cache && php artisan event:cache && php artisan route:cache && php artisan view:cache)
    fi

    if [ "$role" = "app" ]; then

        echo "Running PHP-FPM..."
        exec php-fpm

    elif [ "$role" = "queue" ]; then

        echo "Running the queue..."
        exec php /var/www/html/artisan queue:work -vv --no-interaction --tries=3 --sleep=5 --timeout=300 --delay=10

    elif [ "$role" = "cron" ]; then

        echo "Running the cron..."
        while [ true ]
        do
          exec php /var/www/html/artisan schedule:run -vv --no-interaction
          sleep 60
        done

    else
        echo "Could not match the container role \"$role\""
        exit 1
    fi

else
    exec "$@"
fi

您已完成。下次您停止队列服务时,它将正常停止,并且不会等待10秒的SIGKILL。我认为这与PID 1事情有关。

答案 3 :(得分:-3)

使用主管

apt-get install supervisor

cd /etc/supervisor/conf.d& amp ;& amp; sudo nano laravel-worker.conf

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=docker exec php php /path/to/artisan queue:work redis --sleep=3 --tries=5
autostart=true
autorestart=true
user=root
numprocs=8
redirect_stderr=true
stdout_logfile=/var/logs/worker.log