Skip to content

nginx: add /websockets plural alias with path rewrite to selkies /ws#151

Open
DL6ER wants to merge 1 commit intolinuxserver:masterfrom
DL6ER:fix/nginx-websockets-plural-alias
Open

nginx: add /websockets plural alias with path rewrite to selkies /ws#151
DL6ER wants to merge 1 commit intolinuxserver:masterfrom
DL6ER:fix/nginx-websockets-plural-alias

Conversation

@DL6ER
Copy link
Copy Markdown

@DL6ER DL6ER commented Apr 25, 2026

linuxserver.io


  • I have read the contributing guideline and understand that I have made the correct modifications

Description:

Add an nginx location block for the plural /websockets URL that the selkies-dashboard frontend builds in WebSocket mode, with a path rewrite to selkies' /ws endpoint.

location SUBFOLDERwebsockets {
    proxy_set_header        Upgrade $http_upgrade;
    proxy_set_header        Connection "upgrade";
    ...
    proxy_pass              http://127.0.0.1:CWS/ws;
}

Done in both the :3000 and the :3001 server blocks of root/defaults/default.conf.

Benefits of this PR and context:

Out of the box, opening a freshly started lscr.io/linuxserver/baseimage-selkies-derived container in a browser logs:

Firefox can't establish a connection to the server at wss://<host>/websockets.
[websockets] Error: WebSocket connection refused

Three independent path conventions are in play:

  • The frontend (addons/selkies-web-core/selkies-ws-core.js upstream) builds the URL as ${ws_protocol}${window.location.host}${pathname}websockets (plural).
  • The bundled nginx config in this repo only declares location SUBFOLDERwebsocket {} (singular).
  • The selkies signaling server in src/selkies/signaling_server.py upgrades to WebSocket only for path == "/ws" or paths ending in /signaling.

So even a singular /websocket request would 404 inside selkies.

The proposed change makes the default install work end-to-end without patching either the frontend or selkies, by exposing the URL the frontend already uses and rewriting it to the path the server expects. The existing singular /websocket location is left untouched for backwards compatibility with anything that may already point at it.

How Has This Been Tested?

Built locally from this branch on top of the upstream master (debian-trixie variant), then composed a webtop-style layer on top (debian-xfce) and ran it on a Linux x86_64 host with:

docker run -d \
  -p 3010:3000 \
  -e PUID=1000 -e PGID=1000 -e TZ=Europe/Berlin \
  -e SELKIES_TURN_HOST=... \
  -e SELKIES_TURN_PORT=3478 \
  -e SELKIES_TURN_PROTOCOL=udp \
  -e SELKIES_TURN_SHARED_SECRET=... \
  --shm-size=1g --cap-add SYS_ADMIN \
  webtop:patched

Validated in Firefox 149 and Chromium 142 on Ubuntu:

  • Before patch: NS_ERROR_WEBSOCKET_CONNECTION_REFUSED on wss://<host>/websockets, dashboard fails to load.
  • After patch: WebSocket upgrade returns HTTP/1.1 101 Switching Protocols, dashboard connects, MATE/XFCE desktop renders, input round-trip works.

Also verified directly:

$ curl -i -H 'Upgrade: websocket' -H 'Connection: Upgrade' \
       -H 'Sec-WebSocket-Key: <16 random bytes b64>' \
       -H 'Sec-WebSocket-Version: 13' \
       https://<host>/websockets
HTTP/1.1 101 Switching Protocols

Source / References:

  • Frontend URL construction: addons/selkies-web-core/selkies-ws-core.js upstream of selkies-project/selkies, the line websocketEndpointURL.pathname += 'websockets'.
  • Server-side path matching: src/selkies/signaling_server.py upstream, the process_request method that returns None (i.e. accepts WS upgrade) only for /ws, /ws/, /signaling and /signaling/.

The selkies-dashboard frontend (selkies-web-core/selkies-ws-core.js) builds
its WebSocket-mode connection URL as `${pathname}websockets` (plural),
while the bundled nginx config only routes `/websocket` (singular).
Browsers therefore see NS_ERROR_WEBSOCKET_CONNECTION_REFUSED on first
WebSocket-mode connect.

Even when the singular URL is used, the upstream selkies signaling
server (process_request in src/selkies/signaling_server.py) only
recognises path == "/ws" and paths ending with "/signaling" for the
WebSocket upgrade. Anything else falls through to a 404.

Add a `SUBFOLDERwebsockets` location with `proxy_pass http://127.0.0.1:CWS/ws`,
i.e. plural URL exposed to the client and rewritten to /ws towards selkies.
This makes WebSocket-mode work out of the box without any frontend or
selkies code changes.

Tested with debian-trixie base image, selkies in --mode=websockets and in
dual-mode (SELKIES_ENABLE_DUAL_MODE=true): browser connects, dashboard
loads, stream renders.
Copilot AI review requested due to automatic review settings April 25, 2026 15:56
@LinuxServer-CI LinuxServer-CI moved this to PRs Ready For Team Review in Issue & PR Tracker Apr 25, 2026
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this pull request! Be sure to follow the pull request template!

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the bundled nginx default config to support the selkies-dashboard frontend’s WebSocket URL convention by adding a plural /websockets location that proxies to Selkies’ /ws endpoint.

Changes:

  • Add location SUBFOLDERwebsockets to proxy WebSocket upgrades to http://127.0.0.1:CWS/ws.
  • Apply the same change to both nginx server blocks (ports 3000 and 3001).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@LinuxServer-CI
Copy link
Copy Markdown
Collaborator

I am a bot, here are the test results for this PR:
https://ci-tests.linuxserver.io/lspipepr/selkies-base/debiantrixie-aa141909-pkg-aa141909-dev-8fa3b6b1a0bb92a3326c8d22f6da590f33a25a1a-pr-151/index.html
https://ci-tests.linuxserver.io/lspipepr/selkies-base/debiantrixie-aa141909-pkg-aa141909-dev-8fa3b6b1a0bb92a3326c8d22f6da590f33a25a1a-pr-151/shellcheck-result.xml

Tag Passed
amd64-debiantrixie-aa141909-pkg-aa141909-dev-8fa3b6b1a0bb92a3326c8d22f6da590f33a25a1a-pr-151
arm64v8-debiantrixie-aa141909-pkg-aa141909-dev-8fa3b6b1a0bb92a3326c8d22f6da590f33a25a1a-pr-151

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: PRs Ready For Team Review

Development

Successfully merging this pull request may close these issues.

3 participants