I’m trying to solve this problem I’ve been experiencing wherein I’ve been unable to connect to my SurrealDB backend over HTTPS/WSS. When attempting to connect via HTTP or WS, things work just fine, but adding any sort of SSL seems to break everything. My current stack looks like this:
- nginx – For serving my web content and providing a reverse proxy to the SurrealDB instance on its default port (:8000).
- SurrealDB – The database solution I am using for my site (perhaps one of my favorite db solutions of all time… when it works 😋)
- React with Next.js – The mostly front-end solution for my website.
- Cloudflare – For DNS routing and proxying.
My nginx configuration looks like this:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 127.0.0.1:4321;
}
sendfile on;
keepalive_timeout 65;
# HTTP server
server {
listen 443 ssl;
server_name [...].com;
ssl_certificate C:Certbotlive[...].comfullchain.pem;
ssl_certificate_key C:Certbotlive[...].comprivkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
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;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# Secure WebWocket (WSS) server
server {
listen 443;
server_name dev.db.[...].com;
ssl_certificate C:Certbotlive[...].comfullchain.pem;
ssl_certificate_key C:Certbotlive[...].comprivkey.pem;
location / {
proxy_set_header Host $host;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://websocket;
proxy_redirect off;
proxy_pass_request_headers on;
}
}
}
Cloudflare is setup to forward traffic to the main domain and all subdomains to the same server (everything is currently hosted from the same machine.) Both configuration options (A records) are set to the same IP address and are proxied.
The proxy to port 3000 works and the Next.js instance is accessible via HTTPS, so I don’t imagine that nginx itself is messed up, but I might be wrong.
I have tried various solutions to this problem, including the following:
-
Issuing separate SSL certificates for the subdomain and the primary domain (using certbot),
-
Sharing the same SSL certificate for both domains (using certbot),
-
Pointing
proxy-pass
to anupstream
as well as a direct127.0.0.1:8000
approach, -
Ensuring the following:
proxy_http_version
is set to1.1
.proxy_set_header Upgrade
is set to$http_upgrade
orupgrade
.
-
Listening on both 443 and 80, including and excluding the
ssl
suffix on thelisten
directive. -
Changing the
server_name
fromdev.db.[...].com
to various other options, with no success, -
Port-forwarding port 8000, 443, 80, and 8080.
-
Adding firewall rules (TCP/UDP + incoming/outgoing) for the aforementioned ports, as well as port 3000 (for the Next.js instance).
-
Changing SurrealDB’s address and port binding (
--bind
) to something else. Note that the--addr
flag available when starting SurrealDB is something I have not yet tried as I cannot quite seem to figure out the proper way to manipulate it. Could this be the issue? -
Attempted connection via local network and external WSS port testing tool, both failures,
-
Reordered nginx configuration to use a
location /ws
instead of aserver
directive just to see if that might work (unfortunately it did not).
This is the error I get every single time I attempt to connect from any medium:
Console log error "WebSocket connection to wss://dev.db.censored.com/’ failed
Are there any suggestions? Am I perhaps missing something, or maybe I did this incorrectly?
(Note that the […] in the examples provided is the censored domain name, not literal characters.)
2
Answers
I solved my own problem! The issue was that I was not proxying the
/rpc
endpoint properly in mynginx.conf
. The fix was to add this to my default server entry in the configuration:This allows the JavaScript library to access the correct SurrealDB endpoint and fixed my problem right away. In hindsight, I feel like it should have been obvious, but oh well! If anyone else has a similar problem getting SurrealDB to work with your nginx configuration, I hope this helps!
Glad to see this conversation moved to Github Issues: https://github.com/surrealdb/surrealdb.js/issues/110