Headless browser that renders target web pages (e.g., Home Assistant dashboards) and streams them as image tiles over WebSocket to lightweight clients (ESP32 displays).
- Renders pages in a headless Chromium environment and streams diffs as tiles over WebSocket.
- Tile merging with change detection to reduce packet count and CPU load
- Full-frame fallback on cadence/threshold or on demand
- Configurable tile size, JPEG quality, WS message size, and min frame interval
- Per-client settings: each connection can supply its own width, height, tileSize, jpegQuality, maxBytesPerMessage, etc.
- Hot reconfigure: reconnecting with new params reconfigures the device session and triggers a full-frame refresh.
- Smarter frame gating: throttling + content-hash dedup (skip identical frames)
- No viewers = no work: frames are ACK’d to keep Chromium streaming, but tiles aren’t encoded/queued when there are no listeners.
- Touch event bridging (down/move/up) — scrolling supported (no gestures yet)
- Client-driven navigation: the client can control which page to open.
- Built-in self-test page to visualize and measure render time
- Health endpoint for container orchestration
- Optional DevTools access via TCP proxy
- Make sure your server exposes the DevTools (CDP) port (e.g., 9222).
- In Chrome, go to chrome://inspect/#devices → Configure… → add your host: hostname_or_ip:9222.
- You should see the page the server opened (the one you want to log into, e.g., Home Assistant). Click inspect to open a full DevTools window for that tab.
- latest — newest stable release
- beta — newest pre-release (rolling)
- Semantic versions: X.Y.Z, plus convenience tags X.Y, X on stable releases
You can pin a stable release (1.4.0
) or track channels (latest
, beta
) depending on your deployment strategy.
services:
rwvserver:
image: strangev/remote-webview-server:latest # use :beta for pre-release
container_name: remote-webview-server
restart: unless-stopped
environment:
SCREEN_H: 480
SCREEN_W: 480
TILE_SIZE: 32
FULL_FRAME_TILE_COUNT: 4
FULL_FRAME_AREA_THRESHOLD: 0.5
FULL_FRAME_EVERY: 50
EVERY_NTH_FRAME: 1
MIN_FRAME_INTERVAL_MS: 80
JPEG_QUALITY: 85
MAX_BYTES_PER_MESSAGE: 14336
WS_PORT: 8081
DEBUG_PORT: 9221 # internal debug port
HEALTH_PORT: 18080
USER_DATA_DIR: /pw-data
ports:
- "8081:8081" # WebSocket stream
- "9222:9222" # external DevTools via socat
expose:
- "18080" # health endpoint (internal)
- "9221" # internal DevTools port
volumes:
- /opt/volumes/esp32-rdp/pw-data:/pw-data
shm_size: 1gb
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:18080 || exit 1"]
interval: 10s
timeout: 3s
retries: 5
start_period: 10s
debug-proxy:
image: alpine/socat
container_name: remote-webview-server-debug
restart: unless-stopped
network_mode: "service:rwvserver"
depends_on:
rwvserver:
condition: service_healthy
command:
- "-d"
- "-d"
- "TCP-LISTEN:9222,fork,reuseaddr,keepalive" # external DevTools port
- "TCP:127.0.0.1:9221"