如何将带有通道和 websocket 的 django 应用程序部署到 Heroku?
How to deploy django app with channels and websocket to Heroku?
我正在创建 Messanger。我遇到了将我的应用程序部署到 heroku 的需求。
我的config/settings.py
from pathlib import Path
from datetime import timedelta
import os
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = os.environ.get('SECRET_KEY')
DEBUG = True
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_simplejwt',
'corsheaders',
'users',
'tokens',
'channels',
'chat',
'college'
]
AUTH_USER_MODEL = 'users.User'
ASGI_APPLICATION = 'config.asgi.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [(os.environ.get('REDIS_URI'), 25690)],
},
},
}
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'config.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('ELEPHANT_NAME'),
'USER': os.environ.get('ELEPHANT_USER'),
'PASSWORD': os.environ.get('ELEPHANT_PASSWORD'),
'HOST': os.environ.get('ELEPHANT_HOST'),
'PORT': 5432
}
}
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
........................
我使用 heroku-redis
config.asgi
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import chat.routing
from config.middlewares import TokenAuthMiddleware
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": TokenAuthMiddleware(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
过程文件
release: python manage.py migrate
web: daphne config.asgi:application --port $PORT --bind 0.0.0.0 -v2
worker: python manage.py runworker channels --settings=core.settings -v2
老实说,我不知道应该指定哪个端口。觉得不重要所以离开了8001
requirements.txt
....................
daphne==3.0.2
Django==3.2.9
gunicorn==20.1.0
hiredis==2.0.0
psycopg2==2.9.2
channels==3.0.4
channels-redis==3.3.1
.....................
我收到错误
2021-12-24T13:28:26.164337+00:00 heroku[web.1]: State changed from crashed to starting
2021-12-24T13:28:31.530462+00:00 heroku[web.1]: Starting process with command `daphne config.asgi:application --port 59828 --bind 0.0.0.0 -v2`
2021-12-24T13:28:33.068963+00:00 app[web.1]: Traceback (most recent call last):
2021-12-24T13:28:33.068982+00:00 app[web.1]: File "/app/.heroku/python/bin/daphne", line 8, in <module>
2021-12-24T13:28:33.069042+00:00 app[web.1]: sys.exit(CommandLineInterface.entrypoint())
2021-12-24T13:28:33.069044+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/daphne/cli.py", line 170, in entrypoint
2021-12-24T13:28:33.069151+00:00 app[web.1]: cls().run(sys.argv[1:])
2021-12-24T13:28:33.069160+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/daphne/cli.py", line 232, in run
2021-12-24T13:28:33.069237+00:00 app[web.1]: application = import_by_path(args.application)
2021-12-24T13:28:33.069247+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/daphne/utils.py", line 12, in import_by_path
2021-12-24T13:28:33.069292+00:00 app[web.1]: target = importlib.import_module(module_path)
2021-12-24T13:28:33.069294+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/importlib/__init__.py", line 127, in import_module
2021-12-24T13:28:33.069356+00:00 app[web.1]: return _bootstrap._gcd_import(name[level:], package, level)
2021-12-24T13:28:33.069364+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
2021-12-24T13:28:33.069433+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
2021-12-24T13:28:33.069471+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
2021-12-24T13:28:33.069568+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
2021-12-24T13:28:33.069569+00:00 app[web.1]: File "<frozen importlib._bootstrap_external>", line 850, in exec_module
2021-12-24T13:28:33.069590+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
2021-12-24T13:28:33.069628+00:00 app[web.1]: File "/app/./config/asgi.py", line 6, in <module>
2021-12-24T13:28:33.069680+00:00 app[web.1]: import chat.routing
2021-12-24T13:28:33.069681+00:00 app[web.1]: File "/app/./chat/routing.py", line 3, in <module>
2021-12-24T13:28:33.069727+00:00 app[web.1]: from . import consumers
2021-12-24T13:28:33.069735+00:00 app[web.1]: File "/app/./chat/consumers.py", line 4, in <module>
2021-12-24T13:28:33.069777+00:00 app[web.1]: from .models import Message, Chat, File
2021-12-24T13:28:33.069785+00:00 app[web.1]: File "/app/./chat/models.py", line 3, in <module>
2021-12-24T13:28:33.069827+00:00 app[web.1]: from users.models import User
2021-12-24T13:28:33.069834+00:00 app[web.1]: File "/app/./users/models.py", line 3, in <module>
2021-12-24T13:28:33.069877+00:00 app[web.1]: from django.contrib.auth.models import AbstractUser, Group
2021-12-24T13:28:33.069885+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/auth/models.py", line 3, in <module>
2021-12-24T13:28:33.069930+00:00 app[web.1]: from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
2021-12-24T13:28:33.069938+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/auth/base_user.py", line 48, in <module>
2021-12-24T13:28:33.069991+00:00 app[web.1]: class AbstractBaseUser(models.Model):
2021-12-24T13:28:33.069997+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/db/models/base.py", line 108, in __new__
2021-12-24T13:28:33.070056+00:00 app[web.1]: app_config = apps.get_containing_app_config(module)
2021-12-24T13:28:33.070064+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/apps/registry.py", line 253, in get_containing_app_config
2021-12-24T13:28:33.070148+00:00 app[web.1]: self.check_apps_ready()
2021-12-24T13:28:33.070156+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/apps/registry.py", line 136, in check_apps_ready
2021-12-24T13:28:33.070219+00:00 app[web.1]: raise AppRegistryNotReady("Apps aren't loaded yet.")
2021-12-24T13:28:33.070242+00:00 app[web.1]: django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
2021-12-24T13:28:33.285009+00:00 heroku[web.1]: Process exited with status 1
我该如何解决这个问题?如果你需要我给你看的其他东西,请评论
您需要在导入任何模型之前调用 get_asgi_application
,import chat.routing
似乎会触发模型导入,因此在此导入之前调用 get_asgi_application()
config.asgi
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
django_asgi_app = get_asgi_application()
import chat.routing
from config.middlewares import TokenAuthMiddleware
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": TokenAuthMiddleware(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
我正在创建 Messanger。我遇到了将我的应用程序部署到 heroku 的需求。
我的config/settings.py
from pathlib import Path
from datetime import timedelta
import os
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = os.environ.get('SECRET_KEY')
DEBUG = True
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_simplejwt',
'corsheaders',
'users',
'tokens',
'channels',
'chat',
'college'
]
AUTH_USER_MODEL = 'users.User'
ASGI_APPLICATION = 'config.asgi.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [(os.environ.get('REDIS_URI'), 25690)],
},
},
}
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'config.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('ELEPHANT_NAME'),
'USER': os.environ.get('ELEPHANT_USER'),
'PASSWORD': os.environ.get('ELEPHANT_PASSWORD'),
'HOST': os.environ.get('ELEPHANT_HOST'),
'PORT': 5432
}
}
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
........................
我使用 heroku-redis
config.asgi
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import chat.routing
from config.middlewares import TokenAuthMiddleware
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": TokenAuthMiddleware(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
过程文件
release: python manage.py migrate
web: daphne config.asgi:application --port $PORT --bind 0.0.0.0 -v2
worker: python manage.py runworker channels --settings=core.settings -v2
老实说,我不知道应该指定哪个端口。觉得不重要所以离开了8001
requirements.txt
....................
daphne==3.0.2
Django==3.2.9
gunicorn==20.1.0
hiredis==2.0.0
psycopg2==2.9.2
channels==3.0.4
channels-redis==3.3.1
.....................
我收到错误
2021-12-24T13:28:26.164337+00:00 heroku[web.1]: State changed from crashed to starting
2021-12-24T13:28:31.530462+00:00 heroku[web.1]: Starting process with command `daphne config.asgi:application --port 59828 --bind 0.0.0.0 -v2`
2021-12-24T13:28:33.068963+00:00 app[web.1]: Traceback (most recent call last):
2021-12-24T13:28:33.068982+00:00 app[web.1]: File "/app/.heroku/python/bin/daphne", line 8, in <module>
2021-12-24T13:28:33.069042+00:00 app[web.1]: sys.exit(CommandLineInterface.entrypoint())
2021-12-24T13:28:33.069044+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/daphne/cli.py", line 170, in entrypoint
2021-12-24T13:28:33.069151+00:00 app[web.1]: cls().run(sys.argv[1:])
2021-12-24T13:28:33.069160+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/daphne/cli.py", line 232, in run
2021-12-24T13:28:33.069237+00:00 app[web.1]: application = import_by_path(args.application)
2021-12-24T13:28:33.069247+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/daphne/utils.py", line 12, in import_by_path
2021-12-24T13:28:33.069292+00:00 app[web.1]: target = importlib.import_module(module_path)
2021-12-24T13:28:33.069294+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/importlib/__init__.py", line 127, in import_module
2021-12-24T13:28:33.069356+00:00 app[web.1]: return _bootstrap._gcd_import(name[level:], package, level)
2021-12-24T13:28:33.069364+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
2021-12-24T13:28:33.069433+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
2021-12-24T13:28:33.069471+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
2021-12-24T13:28:33.069568+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
2021-12-24T13:28:33.069569+00:00 app[web.1]: File "<frozen importlib._bootstrap_external>", line 850, in exec_module
2021-12-24T13:28:33.069590+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
2021-12-24T13:28:33.069628+00:00 app[web.1]: File "/app/./config/asgi.py", line 6, in <module>
2021-12-24T13:28:33.069680+00:00 app[web.1]: import chat.routing
2021-12-24T13:28:33.069681+00:00 app[web.1]: File "/app/./chat/routing.py", line 3, in <module>
2021-12-24T13:28:33.069727+00:00 app[web.1]: from . import consumers
2021-12-24T13:28:33.069735+00:00 app[web.1]: File "/app/./chat/consumers.py", line 4, in <module>
2021-12-24T13:28:33.069777+00:00 app[web.1]: from .models import Message, Chat, File
2021-12-24T13:28:33.069785+00:00 app[web.1]: File "/app/./chat/models.py", line 3, in <module>
2021-12-24T13:28:33.069827+00:00 app[web.1]: from users.models import User
2021-12-24T13:28:33.069834+00:00 app[web.1]: File "/app/./users/models.py", line 3, in <module>
2021-12-24T13:28:33.069877+00:00 app[web.1]: from django.contrib.auth.models import AbstractUser, Group
2021-12-24T13:28:33.069885+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/auth/models.py", line 3, in <module>
2021-12-24T13:28:33.069930+00:00 app[web.1]: from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
2021-12-24T13:28:33.069938+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/auth/base_user.py", line 48, in <module>
2021-12-24T13:28:33.069991+00:00 app[web.1]: class AbstractBaseUser(models.Model):
2021-12-24T13:28:33.069997+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/db/models/base.py", line 108, in __new__
2021-12-24T13:28:33.070056+00:00 app[web.1]: app_config = apps.get_containing_app_config(module)
2021-12-24T13:28:33.070064+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/apps/registry.py", line 253, in get_containing_app_config
2021-12-24T13:28:33.070148+00:00 app[web.1]: self.check_apps_ready()
2021-12-24T13:28:33.070156+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/django/apps/registry.py", line 136, in check_apps_ready
2021-12-24T13:28:33.070219+00:00 app[web.1]: raise AppRegistryNotReady("Apps aren't loaded yet.")
2021-12-24T13:28:33.070242+00:00 app[web.1]: django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
2021-12-24T13:28:33.285009+00:00 heroku[web.1]: Process exited with status 1
我该如何解决这个问题?如果你需要我给你看的其他东西,请评论
您需要在导入任何模型之前调用 get_asgi_application
,import chat.routing
似乎会触发模型导入,因此在此导入之前调用 get_asgi_application()
config.asgi
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
django_asgi_app = get_asgi_application()
import chat.routing
from config.middlewares import TokenAuthMiddleware
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": TokenAuthMiddleware(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})