You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Heroku部署Django/Channels(ASGI)应用时出现AppRegistryNotReady错误

在Heroku部署集成Channels的Django ASGI应用时遇到AppRegistryNotReady错误

问题描述

本地运行正常,但部署到Heroku后启动失败,出现AppRegistryNotReady: Apps aren't loaded yet.错误,相关日志及配置如下:

Heroku日志

2023-09-29T13:50:20.958856+00:00 heroku[web.1]: State changed from crashed to starting
2023-09-29T13:50:24.630050+00:00 heroku[web.1]: Starting process with command `daphne nanochat.asgi:application --port 16299 --bind 0.0.0.0 -v2`
2023-09-29T13:50:25.627718+00:00 app[web.1]: Traceback (most recent call last):
2023-09-29T13:50:25.627755+00:00 app[web.1]: File "/app/.heroku/python/bin/daphne", line 8, in <module>
2023-09-29T13:50:25.627769+00:00 app[web.1]: sys.exit(CommandLineInterface.entrypoint())
2023-09-29T13:50:25.627785+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/daphne/cli.py", line 171, in entrypoint
2023-09-29T13:50:25.627826+00:00 app[web.1]: cls().run(sys.argv[1:])
2023-09-29T13:50:25.627827+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/daphne/cli.py", line 233, in run
2023-09-29T13:50:25.627875+00:00 app[web.1]: application = import_by_path(args.application)
2023-09-29T13:50:25.627876+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/daphne/utils.py", line 12, in import_by_path
2023-09-29T13:50:25.627909+00:00 app[web.1]: target = importlib.import_module(module_path)
2023-09-29T13:50:25.627909+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/importlib/__init__.py", line 126, in import_module
2023-09-29T13:50:25.627951+00:00 app[web.1]: return _bootstrap._gcd_import(name[level:], package, level)
2023-09-29T13:50:25.627952+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
2023-09-29T13:50:25.628008+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
2023-09-29T13:50:25.628030+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
2023-09-29T13:50:25.628055+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
2023-09-29T13:50:25.628081+00:00 app[web.1]: File "<frozen importlib._bootstrap_external>", line 883, in exec_module
2023-09-29T13:50:25.628117+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
2023-09-29T13:50:25.628142+00:00 app[web.1]: File "/app/./nanochat/asgi.py", line 16, in <module>
2023-09-29T13:50:25.628169+00:00 app[web.1]: import chat.routing
2023-09-29T13:50:25.628170+00:00 app[web.1]: File "/app/./chat/routing.py", line 3, in <module>
2023-09-29T13:50:25.628195+00:00 app[web.1]: from . import consumers
2023-09-29T13:50:25.628196+00:00 app[web.1]: File "/app/./chat/consumers.py", line 5, in <module>
2023-09-29T13:50:25.628223+00:00 app[web.1]: from .models import Conversation, Message
2023-09-29T13:50:25.628223+00:00 app[web.1]: File "/app/./chat/models.py", line 5, in <module>
2023-09-29T13:50:25.628251+00:00 app[web.1]: from base.models import Company, Customer
2023-09-29T13:50:25.628251+00:00 app[web.1]: File "/app/./base/models.py", line 5, in <module>
2023-09-29T13:50:25.628278+00:00 app[web.1]: class Company(models.Model):
2023-09-29T13:50:25.628278+00:00 app[web.1]: File "/app/./base/models.py", line 20, in Company
2023-09-29T13:50:25.628333+00:00 app[web.1]: staff = models.ManyToManyField(get_user_model(), through='Role')
2023-09-29T13:50:25.628334+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/django/contrib/auth/__init__.py", line 170, in get_user_model
2023-09-29T13:50:25.628356+00:00 app[web.1]: return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
2023-09-29T13:50:25.628357+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/django/apps/registry.py", line 203, in get_model
2023-09-29T13:50:25.628398+00:00 app[web.1]: self.check_apps_ready()
2023-09-29T13:50:25.628398+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/django/apps/registry.py", line 138, in check_apps_ready
2023-09-29T13:50:25.628431+00:00 app[web.1]: raise AppRegistryNotReady("Apps aren't loaded yet.")
2023-09-29T13:50:25.628449+00:00 app[web.1]: django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
2023-09-29T13:50:25.808196+00:00 heroku[web.1]: Process exited with status 1
2023-09-29T13:50:25.838513+00:00 heroku[web.1]: State changed from starting to crashed

配置文件

asgi.py

import os

from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import chat.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nanochat.settings')
django_asgi_app = get_asgi_application()

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": URLRouter(
        chat.routing.websocket_urlpatterns
    ),
})

settings.py

INSTALLED_APPS = [
     'daphne',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'base',
    'accounts',
    'payment',
    'common',
    'utils',
    'notification',
    'rest_framework',
    'rest_framework_simplejwt',
    # 'drf_spectacular',
    'channels',
    'drf_yasg',
    'corsheaders',
    'push_notifications',
    'chat',
    'django.contrib.staticfiles',
]

ASGI_APPLICATION = "nanochat.asgi.application"
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': "channels.layers.InMemoryChannelLayer"
        }
    }

Procfile

release: python manage.py migrate
web: daphne nanochat.asgi:application --port $PORT --bind 0.0.0.0 -v2

成因分析

从日志调用链可以看出,import chat.routing语句在Django应用初始化(get_asgi_application())之前就触发了模型导入——这个导入会递归加载消费者、模型文件,而此时Django的App Registry还未完成初始化,导致调用get_user_model()时抛出错误。

本地运行正常是因为本地环境可能通过启动命令(如runserver)提前完成了Django配置加载,掩盖了导入顺序问题,但Heroku生产环境下Daphne直接加载ASGI应用时,这个顺序问题就会暴露。

解决方案

调整ASGI文件的导入顺序,将路由导入移到Django应用初始化完成之后:

修改后的asgi.py:

import os

from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nanochat.settings')
# 先完成Django应用初始化
django_asgi_app = get_asgi_application()

# 此时App Registry已加载,再导入路由
import chat.routing

application = ProtocolTypeRouter({
    "http": django_asgi_app,  # 复用已初始化的应用实例,避免重复初始化
    "websocket": URLRouter(
        chat.routing.websocket_urlpatterns
    ),
})

额外优化建议

  1. 检查消费者文件,若模块级别直接导入模型,可将导入移到函数内部(比如connect方法里),避免模块加载时触发模型初始化。
  2. 确认requirements.txt中包含daphne和channels,确保Heroku能正确安装依赖。

内容的提问来源于stack exchange,提问作者Evans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:45:52