Summary
The published evoapicloud/evo-nexus-dashboard:latest image ships its Python venv (/workspace/.venv) without the websocket-client package. This silently disables the /terminal/ws proxy, so the in-browser terminal WebSocket never connects — the upgrade request returns HTTP 400 from Werkzeug.
Environment
- Image:
evoapicloud/evo-nexus-dashboard:latest
- Deployment:
docker-compose.hub.yml (unmodified), ports 8080 + 32352 mapped
- Host: Linux, Docker Compose
Symptoms
The dashboard loads fine, but the terminal never connects. Access log shows the WS upgrade repeatedly rejected:
"GET /terminal/api/health HTTP/1.1" 200 -
"GET /terminal/ws HTTP/1.1" 400 -
Diagnosis
The frontend connects same-origin: ws://<host>:8080/terminal/ws, which the Flask dashboard is meant to proxy to the Node terminal-server on :32352.
- Direct handshake to the terminal-server → 101 Switching Protocols (server itself is healthy):
curl -i -N -H 'Connection: Upgrade' -H 'Upgrade: websocket' \
-H 'Sec-WebSocket-Version: 13' -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' \
http://localhost:32352/terminal/ws
# HTTP/1.1 101 Switching Protocols
- Same handshake through the dashboard proxy → 400 from
Werkzeug:
curl ... http://localhost:8080/terminal/ws
# HTTP/1.1 400 BAD REQUEST
# Server: Werkzeug/3.1.8 Python/3.12.13
Container logs reveal the cause — register_websocket_proxy disables itself because websocket-client is absent:
terminal_proxy.register_websocket_proxy: websocket-client not installed;
WebSocket proxy disabled. Add `websocket-client` to dependencies.
Confirmed missing from the venv the app actually runs under (start-dashboard.sh → uv run python .../app.py):
$ docker exec evonexus-dashboard /workspace/.venv/bin/python3 -c "import websocket"
ModuleNotFoundError: No module named 'websocket'
With websocket-client disabled, the WS upgrade falls through to the plain-HTTP proxy route, and Werkzeug rejects the Upgrade request with 400.
Fix
Add websocket-client to the dashboard's dependencies so it's installed into /workspace/.venv at image build time. (flask-sock is already present; only websocket-client is missing.) The code's own warning message already points to this.
Verification
Reinstalling the package into the running venv and restarting resolves it completely — /terminal/ws then returns 101 Switching Protocols and the browser terminal connects:
docker exec evonexus-dashboard sh -c 'cd /workspace && uv pip install websocket-client'
docker restart evonexus-dashboard
Summary
The published
evoapicloud/evo-nexus-dashboard:latestimage ships its Python venv (/workspace/.venv) without thewebsocket-clientpackage. This silently disables the/terminal/wsproxy, so the in-browser terminal WebSocket never connects — the upgrade request returns HTTP 400 from Werkzeug.Environment
evoapicloud/evo-nexus-dashboard:latestdocker-compose.hub.yml(unmodified), ports8080+32352mappedSymptoms
The dashboard loads fine, but the terminal never connects. Access log shows the WS upgrade repeatedly rejected:
Diagnosis
The frontend connects same-origin:
ws://<host>:8080/terminal/ws, which the Flask dashboard is meant to proxy to the Node terminal-server on:32352.Werkzeug:Container logs reveal the cause —
register_websocket_proxydisables itself becausewebsocket-clientis absent:Confirmed missing from the venv the app actually runs under (
start-dashboard.sh→uv run python .../app.py):With
websocket-clientdisabled, the WS upgrade falls through to the plain-HTTP proxy route, and Werkzeug rejects theUpgraderequest with 400.Fix
Add
websocket-clientto the dashboard's dependencies so it's installed into/workspace/.venvat image build time. (flask-sockis already present; onlywebsocket-clientis missing.) The code's own warning message already points to this.Verification
Reinstalling the package into the running venv and restarting resolves it completely —
/terminal/wsthen returns101 Switching Protocolsand the browser terminal connects: