在docker集装箱运行django工人和达芙妮

我有在docker容器中运行的django应用程序。 最近我想通了,我需要添加websockets接口到我的应用程序。 我使用naphx和redis后面的daphne作为caching。 问题是我必须在1个容器中运行django工作人员和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,一切正常。

这是一个古老的问题,但我想我会回答,因为我最近面临同样的问题,并认为我可以在这个问题上有所了解。

Django频道如何工作

Django Channels是Django之上的另一个层,它有两种stream程types:

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

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

为什么它不适合你

因为你只运行worker(consumer),而且它阻塞了接口服务器(producer)的执行。 意思是,没有连接会被接受,工人只是盯着一个空的redis队列。

我是如何工作的

我把达芙妮,redis和工人作为单独的容器运行,以便于缩放。 数据库迁移,静态文件收集等只在达芙妮容器中执行。 此容器将只运行一个实例,以确保没有运行并行数据库迁移。

另一方面,工作人员可以扩大和缩小以处理传入的stream量。

你怎么能使它工作

将您的设置分成至less两个容器。 我不build议在一个容器中运行所有的东西(例如使用Supervisor )。 为什么? 因为当需要缩放设置时,没有简单的方法来完成。 你可以将你的容器扩展到两个实例,但是它只是创build了一个daphne,redis,django的主pipe。如果你把工作人员从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'命令

在你提供的脚本中没有必要运行命令,如果有什么东西可以阻止整个事情,因为它正在等待input的问题(例如“你是否重命名列X到Y?”)。

相反,你可以像这样在一个正在运行的容器中执行它:

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