GitHub Copilot d43270d5dc Harden long-lived SSE and WebSocket connections
Address intermittent stalls seen after many hours by improving liveness detection and failure handling for both streaming channels.

WebSocket changes:
- Added periodic server ping frames and a read deadline refreshed by pong replies.
- On sender write/ping failure, explicitly close the underlying connection so clients promptly observe disconnect and reconnect instead of remaining half-open.

SSE changes:
- Excluded /events from gzip middleware and added X-Accel-Buffering: no to reduce proxy buffering risk.
- Stop the SSE loop on write errors for activity/keepalive frames so dead subscribers are cleaned up immediately.

Tests:
- Added regression coverage for gzip bypass on /events.
- Added regression coverage ensuring SSE handler exits and unsubscribes on write failure.
- Verified with make format && make check.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-15 14:28:09 +00:00
2026-01-21 23:53:57 +00:00
2026-02-14 22:40:47 +00:00

webterm

Icon

webterm serves terminal sessions over HTTP/WebSocket, with a dashboard mode for multiple sessions and live-updating terminal tiles.

This repository is the Go port of the original Python implementation, which is preserved in the python branch.

Screenshot

Features

  • Typeahead find for quickly finding and launching sessions with minimal friction
  • Web terminal with reconnect support
  • Ghostty WebAssembly terminal engine for fast rendering
  • Session dashboard with live SVG screenshots
  • Docker watch mode (webterm-command / webterm-theme labels)
  • Docker compose manifest ingestion
  • CPU sparkline tiles for compose services
  • SSE activity updates for fast dashboard refresh
  • Mobile/touch support with virtual keyboard + draggable keybar
  • Theme/font controls for terminal rendering

Install

Build from source

git clone https://github.com/rcarmo/webterm.git
cd webterm
mkdir -p bin
go build -o ./bin/webterm ./cmd/webterm

The command above produces bin/webterm; you can also build it from repo root with make build-go.

Quick start

Run a default shell session:

go run ./cmd/webterm

Run a specific command:

go run ./cmd/webterm -- htop

Then open http://localhost:8080.

Dashboard modes

Landing manifest

- name: Logs
  slug: logs
  command: docker logs -f my-service
  theme: nord
go run ./cmd/webterm -- --landing-manifest ./landing.yaml

Docker watch

go run ./cmd/webterm -- --docker-watch

Containers with these labels become tiles:

  • webterm-command: command string, or auto for Docker exec
  • webterm-theme: theme name (fallback is xterm palette)

Compose manifest

go run ./cmd/webterm -- --compose-manifest ./docker-compose.yaml

Environment variables

  • WEBTERM_STATIC_PATH: override static asset directory
  • WEBTERM_DOCKER_USERNAME: user for Docker exec sessions
  • WEBTERM_DOCKER_AUTO_COMMAND: override auto command (/bin/bash default)
  • WEBTERM_SCREENSHOT_FORCE_REDRAW: force redraw before screenshots (true/1/yes/on)
  • DOCKER_HOST: Docker daemon endpoint override

Development (Makefile-first)

make install-dev
make check
make race
make test
make bump-patch

Frontend bundle tasks:

make build
make build-fast
make bundle-watch

Docker

docker build -t webterm .
docker run -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 webterm --docker-watch

Web assets are embedded in the Go binary by default (you can still override with WEBTERM_STATIC_PATH). The Dockerfile uses a minimal Alpine runtime stage and only installs ca-certificates plus docker-cli.

S
Description
No description provided
Readme 122 MiB
Languages
Go 51.5%
TypeScript 31%
JavaScript 14.8%
Shell 1.2%
Makefile 0.8%
Other 0.7%