Websocket 404 error after deploying to the domain
I setup websockets (chat module) in my Django application, it is working fine on my local machine but when I deployed my app to amazon ec2 instance with containerization it says 404 Not Found
while testing via the postman.
My ASGI container logs also say the same:
WARNING Not Found: /chat/1/
IP:47942 - - [XX:XX:XX] "GET /chat/1/" 404 4479
Note that there is no problem with Docker containers - I tried on containers too on my local machine, and it worked.
Here is my nginx file:
upstream app-development-asgi {
ip_hash;
server app-development-asgi:8001;
}
upstream app-development-wsgi {
ip_hash;
server app-development-wsgi:8000;
}
server {
listen 80;
server_name domain_name;
location /static/ {
alias /app-development/staticfiles/;
}
location /media/ {
alias /app-development/media/;
}
location /ws/ {
proxy_pass http://app-development-asgi/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
proxy_pass http://app-development-wsgi/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I have asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from django.urls import path
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cruze_development.settings')
application = get_asgi_application()
from cruze_development.middleware import JWTAuthMiddleware
from cruze_development.consumers import ClubFeedConsumer, RideLocationConsumer
application = ProtocolTypeRouter({
"http": application,
"websocket": JWTAuthMiddleware(
URLRouter([
path('ws/chat/<str:room_name>/', ClubFeedConsumer.as_asgi()),
path('ws/location/<str:ride_id>/', RideLocationConsumer.as_asgi()),
])
),
})
wss://mydomain.com/ws/chat/1/
I am trying with both ws
and wss
Help me solve it, man!
UPDATE:
The problem was in my nginx file it is mandatory to use some proxy headers for websockets.
here is my updated nginx file code snippet
location /ws/ {
proxy_pass http://app-development-asgi/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
But now I get 500 error while testing on postman: Container log error:
IP:36032 - - [XX:XX:XX] "WSCONNECTING /chat/1/" - -
ERROR Exception inside application: No route found for path 'chat/1/'.
My requirements.txt
django-cacheops==7.0.1
django-cors-headers==3.14.0
django-debug-toolbar==4.0.0
django-environ==0.4.5
django-mysql==3.9.0
django-ninja==0.22.2
django-redis==5.3.0
django-simple-history==2.12.0
django-storages==1.10
Django==5.0.4
djangorestframework_simplejwt==5.3.1
djangorestframework==3.14.0
psycopg2-binary==2.9.9
pillow==10.4.0
channels==4.1.0
channels_redis==4.2.0
daphne
drf-yasg==1.21.8
firebase-admin==6.6.0
pytz
gunicorn==23.0.0
UPDATE 2:
The second problem was because of nginx which was treating /ws/ differently, when I tried ws/ws/ 2 times it worked. Now for the final solution I have removed ws/ in asgi.py so I don't have to make any changes in my frontend.
my final asgi.py
application = ProtocolTypeRouter({
"http": application,
"websocket": JWTAuthMiddleware(
URLRouter([
path('chat/<str:room_name>/', ClubFeedConsumer.as_asgi()),
path('location/<str:ride_id>/', RideLocationConsumer.as_asgi()),
])
),
})
Hope this helps if anyone is facing the same problem even after years. Have a nice day :)
Answer 1:
The problem was in my nginx file it is mandatory to use some proxy headers for websockets.
here is my updated nginx file code snippet
location /ws/ {
proxy_pass http://app-development-asgi/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
But now I get 500 error while testing on postman: Container log error:
IP:36032 - - [XX:XX:XX] "WSCONNECTING /chat/1/" - - ERROR Exception inside application: No route found for path 'chat/1/'. My requirements.txt
django-cacheops==7.0.1
django-cors-headers==3.14.0
django-debug-toolbar==4.0.0
django-environ==0.4.5
django-mysql==3.9.0
django-ninja==0.22.2
django-redis==5.3.0
django-simple-history==2.12.0
django-storages==1.10
Django==5.0.4
djangorestframework_simplejwt==5.3.1
djangorestframework==3.14.0
psycopg2-binary==2.9.9
pillow==10.4.0
channels==4.1.0
channels_redis==4.2.0
daphne
drf-yasg==1.21.8
firebase-admin==6.6.0
pytz
gunicorn==23.0.0
Answer 2:
The second problem was because of nginx which was treating /ws/ differently, when I tried ws/ws/ 2 times it worked. Now for the final solution I have removed ws/ in asgi.py so I don't have to make any changes in my frontend.
my final asgi.py
application = ProtocolTypeRouter({
"http": application,
"websocket": JWTAuthMiddleware(
URLRouter([
path('chat/<str:room_name>/', ClubFeedConsumer.as_asgi()),
path('location/<str:ride_id>/', RideLocationConsumer.as_asgi()),
])
),
})
Hope this helps if anyone is facing the same problem even after years. Have a nice day :)