Web Sockets - Streaming app

Different gunicorn command? No. It’s a separate process from Daphne. Nothing changes with it.

Ok and do i need to run a Daphne startup command or does having both on a single server mean i only need to run 1 startup command?

Yes. If gunicorn is handling wsgi and Daphne is handling websockets, then they both need to be started.

I’m not sure I’m following what you’re asking here. In this architecture (gunicorn & Daphne), gunicorn and Daphne are two different programs and both need to be running to handle requests.

The picture shown here problem with channel_name outside from consumer - #13 by KenWhitesell is one I use frequently to show the general layout of what components are involved in a deployment and how they are related.

There is one more thing I was reminded of, Daphne / Django Channels does not work well on Windows in its default configuration. I don’t remember the specifics, but there’s something about the event handler having issues. (See Django Channels with Redis slow intialization as one example showing this.)

Ok, i think that is my problem then, i’ve not been starting the Daphne application.

would this be the startup command

daphne -b 0.0.0.0 -p 8001 mysite.asgi:application

I assume the port can be anything i like.

Sorry for the silly questions, Im missing the bits around running both within the same container.

This is the basic command, yes.

However, in the absence of other controls or limiting factors, binding these processes to 0.0.0.0 makes it possible for people to connect to this directly and not go through nginx. (This is true for both commands you’ve shown.) When you’re running these behind a web server, you want the web server to be the only process that can connect to these app servers. (Unfortunately, I’m not familiar with the environment you’re trying to use, and so can’t offer any specific suggestions. I have to rely on the general principles that I’m familiar with.)

These are far from “silly”. Proper deployments are a complex topic with lots of moving pieces, many related options, and tons of potential pitfalls.

If by “container” you’re talking about a Docker container, then you don’t want to run both of these in the same. Split them out into separate containers. (I’m strongly in the camp of “One “primary” process per container.” I’ve tried it the other way and have always come back to this.)

Would this mean running two Django apps onc with channels and one as my app? If my consumers are linked to my app models how does that work?

No, it can all reside in one app. (Personally, I do have mine separated into two apps - one containing the Channels Consumer and related code, and another for all the “regular Django” code.)

Note that it’s still one project. A Django project can contain many apps.

They’re just two apps. Why would this be any different than any other situation?

It was this line. I am using docker containers, so splitting into separate containers?

My most common deployment consists of the following containers:

  • Django project running under uwsgi
  • Channels consumer running in Daphne
  • “n” Channels worker containers, each running under an instance of runworker
  • nginx
  • Celery
  • Celery beats
  • Postfix
    (Go back about 5 years or so, and you would have also seen containers for Memcached and RabbitMQ - both of which that have now been retired in favor of Redis)

We do not deploy either PostgreSQL or Redis into containers.

I can’t get this to work.

Im getting this error

24/01/2025, 16:50:56

mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/bin/daphne", line 8, in <module>
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
sys.exit(CommandLineInterface.entrypoint())

But runs locally perfectly.

Any ideas?

I’d need to see all the relevent details (docker files, script contents, full error messages, docker runtime logs, etc.)

It looks like gunicorn starts ok, then when it starts Daphne its throws a load of errors?

mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Wait complete.
24/01/2025, 16:50:51
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Collect static files
24/01/2025, 16:50:53
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
24/01/2025, 16:50:53
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
0 static files copied, 136 unmodified.
24/01/2025, 16:50:53
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Run migrations
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Operations to perform:
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Apply all migrations: admin, auth, contenttypes, posts, sessions, terminal
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Running migrations:
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
No migrations to apply.
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Starting Gunicorn server
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Starting Daphne server
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
[2025-01-24 16:50:55 +0000] [11] [INFO] Starting gunicorn 23.0.0
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
[2025-01-24 16:50:55 +0000] [11] [INFO] Listening at: http://0.0.0.0:8000 (11)
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
[2025-01-24 16:50:55 +0000] [11] [INFO] Using worker: sync
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
[2025-01-24 16:50:55 +0000] [13] [INFO] Booting worker with pid: 13
24/01/2025, 16:50:55
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
[2025-01-24 16:50:55 +0000] [14] [INFO] Booting worker with pid: 14
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
Traceback (most recent call last):
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/bin/daphne", line 8, in <module>
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
sys.exit(CommandLineInterface.entrypoint())
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/lib/python3.11/site-packages/daphne/cli.py", line 171, in entrypoint
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
cls().run(sys.argv[1:])
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/lib/python3.11/site-packages/daphne/cli.py", line 233, in run
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
application = import_by_path(args.application)
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/lib/python3.11/site-packages/daphne/utils.py", line 17, in import_by_path
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
target = importlib.import_module(module_path)
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
return _bootstrap._gcd_import(name[level:], package, level)
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/code/mysite/asgi.py", line 16, in <module>
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
import terminal.routing
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
^^^^^^^^^^^^^^^^^^^^^^^
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/code/terminal/routing.py", line 2, in <module>
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
from . import consumers
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/code/terminal/consumers.py", line 3, in <module>
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
from posts.models import Response
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/code/posts/models.py", line 5, in <module>
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
class Post(models.Model):
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 129, in __new__
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
app_config = apps.get_containing_app_config(module)
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/lib/python3.11/site-packages/django/apps/registry.py", line 260, in get_containing_app_config
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
self.check_apps_ready()
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
File "/usr/local/lib/python3.11/site-packages/django/apps/registry.py", line 138, in check_apps_ready
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
raise AppRegistryNotReady("Apps aren't loaded yet.")
24/01/2025, 16:50:56
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
01/01/1970, 01:00:00
mysite-66fdff5c7d-bm8xk
8965d5422eed9c120e012f9b792c5d4fc5bdcc1c80a82e61eec4594280252023
INSTALLED_APPS = [
    'daphne',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.humanize',
    'posts',
    'terminal',
    'storages',
    'auth0'
]

I will look to run improve with your suggestions, Ken. I just want to see if i can get this working in Dev as it is so i have something to work with.

It looks like it might be a path issue? Maybe it can’t locate any of the from x import ?

It definetly seems it can’t locate the apps/models?

Collect static files

0 static files copied, 136 unmodified.
Run migrations
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, posts, sessions, terminal
Running migrations:
  No migrations to apply.
Starting Gunicorn server
Starting Daphne server
[2025-01-25 07:24:37 +0000] [11] [INFO] Starting gunicorn 23.0.0
[2025-01-25 07:24:37 +0000] [11] [INFO] Listening at: http://0.0.0.0:8000 (11)
[2025-01-25 07:24:37 +0000] [11] [INFO] Using worker: sync
[2025-01-25 07:24:37 +0000] [13] [INFO] Booting worker with pid: 13
[2025-01-25 07:24:37 +0000] [14] [INFO] Booting worker with pid: 14
Traceback (most recent call last):
  File "/usr/local/bin/daphne", line 8, in <module>
    sys.exit(CommandLineInterface.entrypoint())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/daphne/cli.py", line 171, in entrypoint
    cls().run(sys.argv[1:])
  File "/usr/local/lib/python3.11/site-packages/daphne/cli.py", line 233, in run
    application = import_by_path(args.application)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/daphne/utils.py", line 17, in import_by_path
    target = importlib.import_module(module_path)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/code/mysite/asgi.py", line 8, in <module>
    from terminal.routing import websocket_urlpatterns
  File "/code/terminal/routing.py", line 2, in <module>
    from . import consumers  # Corrected import
    ^^^^^^^^^^^^^^^^^^^^^^^
  File "/code/terminal/consumers.py", line 2, in <module>
    from posts.models import Response
  File "/code/posts/models.py", line 5, in <module>
    class Post(models.Model):
  File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 129, in __new__
    app_config = apps.get_containing_app_config(module)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/apps/registry.py", line 260, in get_containing_app_config
    self.check_apps_ready()
  File "/usr/local/lib/python3.11/site-packages/django/apps/registry.py", line 138, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

This is the logs from the container.

my Dockerfile

# Dockerfile

# Use an official Python runtime as a parent image
FROM python:3.11

# Set environment variables to use .env file
ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE=mysite.settings

# Copy the requirements and install dependencies
COPY requirements.txt requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . /code
WORKDIR /code

# Copy the .env file for local development
#COPY .env /code/.env

# Copy the entrypoint script into the container
COPY entrypoint.sh /code/entrypoint.sh
RUN chmod +x /code/entrypoint.sh

# Expose the port for the Django app
EXPOSE 8000

ENTRYPOINT ["/code/entrypoint.sh"]

entrypoint.sh

#!/bin/sh
export DJANGO_SETTINGS_MODULE=mysite.settings

echo "Waiting for 10 seconds to ensure the database is ready..."
sleep 10
echo "Wait complete."

## Collect static files
echo "Collect static files"
python manage.py collectstatic --noinput

# Run migrations
echo "Run migrations"
python manage.py migrate

# Start Gunicorn server
echo "Starting Gunicorn server"
gunicorn -w 2 -b 0.0.0.0:8000 mysite.wsgi:application &

# Start Daphne server for WebSocket connections
echo "Starting Daphne server"
DJANGO_SETTINGS_MODULE=mysite.settings daphne -b 0.0.0.0 -p 8090 mysite.asgi:application
echo "Daphne server started"

Im not sure why this is throwing those errors? What am i missing

I’ve finally got Daphne working.

But my websocket is still disconnecting
terminal.js:29 WebSocket closed unexpectedly

136 static files copied.
Run migrations
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, posts, sessions, terminal
Running migrations:
  No migrations to apply.
Starting Gunicorn server
Starting Daphne server
[2025-01-25 07:59:17 +0000] [11] [INFO] Starting gunicorn 23.0.0
[2025-01-25 07:59:17 +0000] [11] [INFO] Listening at: http://0.0.0.0:8000 (11)
[2025-01-25 07:59:17 +0000] [11] [INFO] Using worker: sync
[2025-01-25 07:59:17 +0000] [13] [INFO] Booting worker with pid: 13
[2025-01-25 07:59:17 +0000] [14] [INFO] Booting worker with pid: 14
2025-01-25 07:59:18,931 INFO     Starting server at tcp:port=8090:interface=0.0.0.0
2025-01-25 07:59:18,931 INFO     HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2025-01-25 07:59:18,931 INFO     Configuring endpoint tcp:port=8090:interface=0.0.0.0
2025-01-25 07:59:18,932 INFO     Listening on TCP address 0.0.0.0:8090

Now I’m think this is because Daphne is running on 8090 and i only have a route to 8000 on my ingress controller?

That is a likely possibility.

Assuming you’re doing something like specifying that the websocket is connecting through a url starting with /ws/, then you need to configure your ingress controller to route those urls to port 8090 instead of 8000.

I’ve added the route on my ingress, now im getting errors from the logs
/ws 404 not found.

routing.py

from django.urls import re_path
from . import consumers  # Corrected import

websocket_urlpatterns = [
    re_path(r'ws/socket-server/', consumers.ChatConsumer.as_asgi()),
]
from django.contrib import admin
from django.urls import path
from posts import views as post_views
from terminal.consumers import ChatConsumer
from django.urls import re_path
from auth0 import views as auth0_views
from terminal import views as terminal_views

urls.py (Project)
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', post_views.landing_page, name='landing_page'),
    path('posts/', post_views.post_list, name='post_list'),
    path('auth/login/', auth0_views.auth0_login, name='login'),
    path('auth/logout/', auth0_views.auth0_logout, name='logout'),
    path('auth/callback/', auth0_views.callback, name='callback'),
    path(".well-known/health/live", auth0_views.health_check, name="health_check"),
    path('terminal/', terminal_views.terminal, name='terminal'),
    path('update-post/<int:post_id>/', terminal_views.update_post, name='update_post'),
    path('abandon-post/<int:post_id>/', terminal_views.abandon_post, name='abandon_post'),
    re_path(r'ws/socket-server/$', ChatConsumer.as_asgi()),
]

WebSocket connection to 'wss://....com/ws/socket-server/' failed:

2025-01-25 13:10:21,636 WARNING  Not Found: /ws
10.230.9.198:32676 - - [25/Jan/2025:13:10:21] "GET /ws" 404 179

What’s the url that you have defined for your websocket connection?

That’s the url that you need to connect to.

Where do you mean? Within my project or in the ingress controller?

for the ingress i am just using the origin as host.mysite.com which has a path rule to route anything /ws to the port 8090 on my django app

So my url would be mysite.com/ws/socket-server/ as set in my routing.py

websocket_urlpatterns = [
    re_path(r'ws/socket-server/', consumers.ChatConsumer.as_asgi()),
]

I’m assuming that the websocket attempt hits my application gateway which then upgrades to a websocket connection.

But i have a feeling that the /ws request is not going to Daphne but to gunicorn? I have no evidence of this but would that explain the /ws 404 not found? maybe the request is not being upgraded to websockets connection.

That’s the wrong url.

You need to issue the websocket connection request on the url defined for your ChatConsumer.

websocket_urlpatterns = [
    re_path(r'ws/socket-server/', consumers.ChatConsumer.as_asgi()),
]

Im not seeing where im going wrong, Ken. What have you spotted?

Are you saying that my path rule should be /ws/*