在码头工人容器中运行django worker和daphne

时间:2016-06-19 09:00:08

标签: django docker channels

我有在docker容器中运行的django应用程序。最近我发现我需要在我的应用程序中添加websockets接口。我在nginx和redis后面使用带有daphne的通道作为缓存。问题是我必须在1个容器中运行django worker和daphne。 在容器启动时运行的脚本:

#!/usr/bin/env bash

python wait_for_postgres.py
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic --no-input

python manage.py runworker --only-channels=http.* --only-channels=websocket.* -v2
daphne team_up.asgi:channel_layer --port 8000 -b 0.0.0.0

但它依赖于经营一名工人。我试过nohup,但它似乎不起作用。如果我直接从带有docker exec的容器运行daphne,一切正常。

1 个答案:

答案 0 :(得分:6)

这是一个老问题,但我想我无论如何都会回答它,因为我最近遇到了同样的问题,并认为我可以对此有所了解。

Django渠道如何运作

Django Channels是Django之上的另一个层,它有两种处理类型:

  • 接受HTTP / Websockets的人
  • 运行Django视图,Websocket处理程序,后台任务等的人

基本上,当一个请求进入时,它首先命中接口服务器(Daphne),它接受HTTP / Websocket连接并将其放在Redis队列上。然后工作者(消费者)看到它,将其从队列中取出并运行视图逻辑(例如Django视图,WS处理程序等)。

为什么它不适合你

因为您只运行worker(使用者)并且它阻止了接口服务器(producer)的执行。意思是,不会接受任何连接,工人只是盯着一个空的redis队列。

我是如何运作的

我将Daphne,redis和工作人员作为单独的容器运行,以便轻松扩展。数据库迁移,静态文件收集等仅在Daphne容器中执行。此容器只运行一个实例,以确保没有并行的数据库迁移运行。

另一方面,工作人员可以按比例放大以处理传入的流量。

如何使其发挥作用

将您的设置拆分为至少两个容器。我不建议在一个容器中运行所有内容(例如,使用Supervisor)。为什么?因为在缩放设置的时候,没有简单的方法可以做到这一点。您可以将容器扩展为两个实例,但这只是创建另一个带有daphne,redis,django的主管...如果您将工作人员从daphne拆分,您可以轻松扩展工作容器以处理不断增长的传入请求。

可以运行一个容器:

#!/usr/bin/env bash

python wait_for_postgres.py
python manage.py migrate
python manage.py collectstatic --no-input

daphne team_up.asgi:channel_layer --port 8000 -b 0.0.0.0

而另一个:

#!/usr/bin/env bash

python wait_for_postgres.py
python manage.py runworker --only-channels=http.* --only-channels=websocket.* -v2

' makemigrations'命令

没有必要在你提供的脚本中运行命令,如果它可以阻止整个事情,因为它正在等待输入的一些问题(例如"你是否将列X重命名为Y?&# 34。)

相反,您可以在这样的运行容器中执行它:

docker exec -it <container_name> python manage.py makemigrations