Novu Websocket fails (Websocket error)
I have novu setup (self hosted) with a nginx reverse proxy. While the Web Dashboard, the api, etc.. seem to work as they should, somehow the React Notifications center does not work because of this websocket error, which i cannot resolve:
WebSocket connection to 'wss://notifications.example.com/socket.io/?EIO=4&transport=websocket' failed:
(domain replaced with example.com)
Has anyone gotten this error already? Getting very frustrated from trying to debug this.
My Novu
.env
file:
# Root URL
REACT_APP_WS_URL=https://notifications.example.com/ws
# Uncomment this one when deploying Novu in the local environment
# as Web app local Dockerfile will have to load this to be used.
# Deployment version doesn't need as we inject it with API_ROOT_URL value.
# REACT_APP_API_URL=http://localhost:3000
API_ROOT_URL=https://notifications.example.com/api
DISABLE_USER_REGISTRATION=true
FRONT_BASE_URL=http://notifications.example.com
WIDGET_EMBED_PATH=https://notifications.example.com/embed.umd.min.js
WIDGET_URL=https://notifications.example.com/widget
# Context Paths
# Only needed for setups with reverse-proxies
GLOBAL_CONTEXT_PATH=
WEB_CONTEXT_PATH=
API_CONTEXT_PATH=api
WS_CONTEXT_PATH=ws
WIDGET_CONTEXT_PATH=widget
In my React component i configure the NovuProvider like this:
backendUrl=https://notifications.example.com/api
socketUrl=https://notifications.example.com/ws
As said, my dashboard, the login, the api itself, etc.. all works. I see the notification center and can opt-in and opt-out of channels, etc... it's just the service worker which does not connect.
Calling this url in the browser (https://notifications.example.com/ws/) directly gives me:
Hello World!
docker ps
indicates that all docker containers are running on their correct ports, docker logs ws
looks like the ws container started successfully. The healthcheck (https://notifications.example.com/ws/v1/health-check). Also gives a success on everything.10 Replies
What i also don't understand, even tho i configured the socket url for the react component, it does not seem to prefix this request:
wss://notifications.example.com/socket.io/?EIO=4&transport=websocket'
With the socket url path (/ws/) but i think that is intentional here?
Even if i hardcode prefix the path and test, the error presists
And here is my nginx proxy config:
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_pass http://localhost:4200/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_pass_header Server;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
location /ws/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_pass http://localhost:3002/ws/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_pass_header Server;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_read_timeout 3000s;
proxy_connect_timeout 750s;
}
@Emil This is the new support ticket 🙂@Tobias what version of react component are you using?
@Emil 0.22.0
Hi @Tobias
As per information shared by you, All looks good
You mentioned that ws service health check is working fine as well
Yes that is correct, or at least seems to be, i attached a screenshot of the healthcheck
@Pawan Jain That is the result io get when i call /ws/v1/health-check
@Pawan Jain @Emil After going through what looks like every discord chat in this server with the letters "ws" in it, i found the solution....not using any context paths whatsoever in the .env file, and then also proxying the /socket.io/ request url.....took me way to much time... i found quite some issues all over discord and on the web with people sturggeling with the same error, so idk maybe you wanna add this to the documenation or so, or make a default nginx example config available.... Thanks to the discord (special thanks to you @ad_schwartz it was your config that fixed it), everything now works! 🙂 this is a basic working nginx config which should do the trick:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://novu_api:3000/;
proxy_redirect off;
proxy_set_header Host $host;
}
location /widget_embed {
rewrite /widget_embed/(.*) /$1 break;
proxy_pass http://novu_widget:4701/;
proxy_redirect off;
proxy_set_header Host $host;
}
location /socket.io {
rewrite /socket.io/(.*) /socket.io/$1 break;
proxy_pass http://novu_ws:3002/;
# usual proxy header
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
# websocket
proxy_http_version 1.1;
# http://nginx.org/en/docs/http/websocket.html
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
}
location / {
proxy_pass http://novu_web:4200/;
proxy_redirect off;
proxy_set_header Host $host;
}
}
@Tobias Thanks so much for sharing! We will include this in our documentation.
This is my config file for my websocket which runs on https://sample.sample.com:8847/
Following your solution how would i change it to make it work?
server {
listen 8447 http2 ssl;
server_name sample.sample.com;
access_log /var/log/nginx/sample.sample.com;
error_log /var/log/nginx/sample.sample.com;
location /.well-known/acme-challenge/ {
root /var/www/html/test; # Temp for generating letsencrypt
default_type text/plain;
}
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
#Fix the “It appears that your reverse proxy set up is broken” error.
proxy_pass http://127.0.0.1:3002;
proxy_read_timeout 90;
proxy_redirect http://127.0.0.1:3002 http://sample.sample.com/;
#Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
}
ssl_certificate /etc/letsencrypt/live/sample.sample.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/sample.sample.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
@Emil tagging you on this