django - 使用 django 频道的 heroku 的正确 procfile / 要求是什么?
问题描述
tl;dr - django 频道应用程序使用 manage.py runserver 在本地运行,但不在 heroku 上。
我是 django 频道的新手 - 尝试使用频道到 heroku 部署一个非常基本的 django 应用程序。我最初使用标准django polls 教程构建了项目,并将其部署到 heroku。然后我使用django 频道教程添加了一个聊天应用程序。按照他们的建议和“python manage.py runserver”,使用 docker 来运行 redis 服务器,设法在本地正常运行。
我试图将它部署到heroku或使用heroku local在本地运行它时遇到了困难。我已经在 heroku 中添加了 redis 插件并修改了 settings.py 以指向 REDIS_URL 环境变量。如果合适的话,我还修改了我的模板以使用 wss(我相信这对于 heroku 来说是必要的):
var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
var target = ws_scheme + '://'
+ window.location.host
+ '/ws/chat/'
+ roomName
+ '/';
const chatSocket = new WebSocket(
target
);
...
因此,我得出的结论是问题出在 procfile 上。我不确定那里的使用说明是什么。最初使用的民意调查教程:
web: gunicorn gettingstarted.wsgi --log-file -
如果我只是使用“heroku local”工作正常并且部署工作正常,但是当我尝试发送聊天消息时它什么也不做,并在控制台中显示 404。我知道我必须将其更改为使用 asgi 服务器而不是 gunicorn。发现本教程部署一个带有通道到heroku的应用程序,它使用:
web: daphne chat.asgi:channel_layer --port $PORT --bind 0.0.0.0 -v2
worker: python manage.py runworker -v2
我试过了,但这就是我卡住的地方。这是我在本地运行 heroku 时得到的结果:
krishnas-air:python-getting-started Krishna$ heroku local
[OKAY] Loaded ENV .env File as KEY=VALUE Format
6:46:50 PM worker.1 | Traceback (most recent call last):
6:46:50 PM worker.1 | File "manage.py", line 8, in <module>
6:46:50 PM worker.1 | from django.core.management import execute_from_command_line
6:46:50 PM worker.1 | ImportError: No module named django.core.management
[DONE] Killing all processes with signal SIGINT
6:46:50 PM worker.1 Exited with exit code null
6:46:50 PM web.1 | Traceback (most recent call last):
6:46:50 PM web.1 | File "/usr/local/bin/daphne", line 5, in <module>
6:46:50 PM web.1 | from daphne.cli import CommandLineInterface
6:46:50 PM web.1 | File "/usr/local/lib/python3.7/site-packages/daphne/cli.py", line 1, in <module>
6:46:50 PM web.1 | import argparse
6:46:50 PM web.1 | File "<frozen importlib._bootstrap>", line 983, in _find_and_load
6:46:50 PM web.1 | File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
6:46:50 PM web.1 | File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
6:46:50 PM web.1 | File "<frozen importlib._bootstrap_external>", line 724, in exec_module
6:46:50 PM web.1 | File "<frozen importlib._bootstrap_external>", line 857, in get_code
6:46:50 PM web.1 | File "<frozen importlib._bootstrap_external>", line 525, in _compile_bytecode
6:46:50 PM web.1 | KeyboardInterrupt
6:46:50 PM web.1 Exited with exit code null
导入错误消息让我认为我的 requirements.txt 可能缺少某些内容,因此我也将其包含在此处以供参考:
django
gunicorn
django-heroku
requests
channels
channels_redis
asgi_redis
asgiref
daphne
redis
gevent
gevent-websocket
greenlet
谢谢你的帮助!
解决方案
我刚刚发现了一个非常相似的问题。首先,虽然不是 Heroku 特有的,但这些文档是必读的。
我认为问题在于 Heroku 是ws://
通过 WSGI 而不是 ASGI 路由请求。所以第一步是asgi.py
在同一个文件夹中创建一个文件,wsgi.py
如下所示:
import django
from channels.routing import get_default_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dropdjango.settings")
django.setup()
application = get_default_application()
然后,在 Procfile 中,定义 dynos 为web
worker
:
web: daphne <my-web-app>.asgi:application --port $PORT --bind 0.0.0.0 -v2
worker: python manage.py runworker channel_layer -v2
如果 Heroku 中尚不存在测功机,请使用 Heroku CLI 创建它们。就我而言,web
测功机已经存在,所以我只创建了worker
测功机:
heroku ps:scale worker=1:free -a <your-heroku-app-name>
最后,仔细检查你的settings.py
,确保你有:
ASGI_APPLICATION="<my-web-app>.routing.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {"hosts": [os.environ.get("REDIS_URL", "redis://localhost:6379")]},
},
}
警告:这将通过 daphne 运行您的所有请求。我读过警告,但我还没有经历过。
推荐阅读
- regex - 正则表达式 .+ 匹配过大
- angular - 在 Kendo 中为 Angular 下拉列表设置字体大小
- python - 无法更新或安装新的 Anaconda 软件包,也无法更新 Conda 根目录
- vb6 - 运行时错误 5:无效的过程调用或参数
- linux-kernel - libc malloc vs linux内核伙伴分配器
- mysql - 通过将列名 acc_no 更改为 account_no 从 TRANSACTION 表创建另一个表 TRANS_TEMP
- javascript - 点击外部 - PIXI JS
- node.js - mongoose.model() 做什么?它返回什么?
- r - R通过过滤时间变量合并2个数据帧
- javascript - `this` 未设置为猴子修补原型方法中的当前对象