WebSocket service behind nginx reverse proxy
Mario Nachbaur
Posted on January 24, 2023
I have all my backend services behind a nginx reverse proxy. It allows me to host many services with different URLs on the same machine, when they're lightweight enough. And it manages SSL and everything needed for secure connections for me, so I can keep my code simple.
The latest service I'm working on relies a lot on WebSockets. Most browsers only allow wss://
(secure web sockets) connections from web pages served with https://
. So I needed to serve the socket with SSL.
Configuration
For a successful web socket connection, we need to ensure that the HTTP version is correct and pass some headers to the service.
server {
location /ws {
proxy_http_version 1.1;
proxy_pass http://address:port;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
}
}
This configuration only applies to the /ws
route, because that is where the socket is. We set the HTTP version to 1.1
since nginx uses 1.0
by default, and forward the Connection
and Upgrade
HTTP headers to the service.
Keeping the socket open
The first thing I noticed after setting up the reverse proxy is that my connections were closing after a while. Turns out nginx closes connections that don't send any data within 60 seconds. You can increment this timeout thanks to the proxy_read_timeout
directive:
location /ws {
# ...
proxy_read_timeout 300s;
}
But I opted to send ping
messages periodically from the client to tell the service that I'm still interested in keeping the connection open. I didn't like the idea of setting the timeout to some large time amount and have a connection open indefinitely.
Posted on January 24, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.