Skip to content

Terminal WebSocket fails with HTTP 400 — evo-nexus-dashboard image is missing websocket-client #115

Description

@arksigma

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.shuv 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions