运行 celery worker + 在同一个容器中打

Running celery worker + beat in the same container

我的 Flask 应用程序由四个容器组成:Web 应用程序、postgres、rabbitMQ 和 Celery。因为我有定期 运行 的芹菜任务,所以我正在使用 celery beat。我已经像这样配置了我的 docker-compose 文件:

version: '2'
services:
  rabbit:
    # ...      
  web:
    # ...
  rabbit:
    # ...
  celery:
    build:
        context: .
        dockerfile: Dockerfile.celery

我的 Dockerfile.celery 看起来像这样:

# ...code up here...
CMD ["celery", "-A", "app.tasks.celery", "worker", "-B", "-l", "INFO"]

虽然我在文档中读到我不应该使用 -B 选项进行生产,但我还是匆忙添加了它(忘记了更改它)并很快了解到我的计划任务是 运行宁多次。对于那些感兴趣的人,如果你从你的 celery 容器中执行 ps aux | grep celery,你会看到多个 celery + beat 进程 运行ning(但应该只有一个 beat 进程和许多工作进程)。我从文档中不确定为什么你不应该 运行 -B 在生产中,但现在我知道了。

然后我将 Dockerfile.celery 更改为:

# ...code up here...
CMD ["celery", "-A", "app.tasks.celery", "worker", "-l", "INFO"]
CMD ["celery", "-A", "app.tasks.celery", "beat", "-l", "INFO"]

不,当我启动我的应用程序时,工作进程启动但 beat 没有。当我翻转这些命令以便首先调用节拍时,节拍开始但工作进程没有。所以我的问题是:如何 运行 celery worker + 在我的容器中一起打?我已经梳理了很多articles/docs,但我仍然无法弄清楚。

已编辑

我将 Dockerfile.celery 更改为以下内容:

ENTRYPOINT [ "/bin/sh" ]
CMD [ "./docker.celery.sh" ]    

我的 docker.celery.sh 文件如下所示:

#!/bin/sh -ex
celery -A app.tasks.celery beat -l debug &
celery -A app.tasks.celery worker -l info &

但是,我收到错误 celery_1 exited with code 0

编辑#2

我在我的 docker.celery.sh 文件末尾添加了以下阻止命令,所有内容都已修复:

tail -f /dev/null

docker 运行 只有一个 CMD,所以只有第一个 CMD 被执行,解决方法是创建一个 bash 脚本来执行 worker 和 beat 并使用 docker CMD 执行这个脚本

您可以使用 celery beatX 进行节拍。允许(并推荐)有多个 beatX 实例。他们使用锁来同步。

不能说它是不是 production-ready,但它对我来说很有用(使用 -B 键)

我按照上面解释的那样输入了入口点,另外我添加了 &> 以在日志文件中输出。

我的entrypoint.sh

#!/bin/bash
python3 manage.py migrate

python3 manage.py migrate catalog --database=catalog

python manage.py collectstatic --clear --noinput --verbosity 0


# Start Celery Workers
celery worker --workdir /app --app dri -l info &> /log/celery.log  &

# Start Celery Beat
celery worker --workdir /app --app dri -l info --beat &> /log/celery_beat.log  &

python3 manage.py runserver 0.0.0.0:8000

从相同的概念@shahaf I solved starting from this 以这种方式使用 bash -c 的其他解决方案开始:

command: bash -c "celery -A app.tasks.celery beat & celery -A app.tasks.celery worker --loglevel=debug"