Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to deploy django app with channels and websocket to Heroku?

I’m creating messanger. I met a need to deploy my app to heroku.

My 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')
........................

I user heroku-redis

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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
        )
    ),
})

Procfile

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

Honestly I don’t know which port i should specify. Don’t think it matters so I left 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
.....................

error i’m getting

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

How can I solve this? If you need something else me to show you please comment

>Solution :

You need to call get_asgi_application before any models are imported, import chat.routing seems to trigger model imports so call get_asgi_application() before this import

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
        )
    ),
})
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading