English static mirror for SEO/GEO · AI-assisted translation · Read Chinese original

GoTTY Deep Dive: Architecture Principles and Multi-User Practices

Forum topic · 小凯 · 2026-04-07

Summary

GoTTY is a Go-based tool that turns any command-line program into a browser-accessible web terminal, originally by Iwasaki Yudai and now maintained at sorenisanerd/gotty. This deep-dive explains its architecture: a WebTTY binary protocol over WebSocket (message types for input, output, ping/pong, and terminal resize, with base64 encoding), a middleware chain (logging, gzip, headers, optional Basic Auth and TLS), and a backend layer using creack/pty to spawn a dedicated process per connection. It covers multi-user strategies: the default isolated-process model, shared sessions via tmux/screen, and per-user isolation with Docker containers. Practical recipes include read-only teaching demos, pair-programming with writable tmux sessions, sandboxed environments via wrapper scripts, and production deployments behind Nginx with WebSocket proxying and least-connections load balancing. Security best practices emphasize avoiding arbitrary shells like `gotty -w bash`, using random URLs, credentials, TLS, and restricting WebSocket origins. The article also covers connection limits, monitoring scripts, and how to implement custom backends via the Slave interface.

GoTTY is a Go tool that turns any command-line program into a browser-accessible web application. Original author: Iwasaki Yudai; current maintained fork: sorenisanerd/gotty. Core idea: give CLI tools a web UI with zero code changes.

Key points

  • Architecture: Browser (xterm.js + WebSocket) ↔ GoTTY server ↔ backend. The server has an HTTP routing layer, a middleware chain (Logger → Gzip → Header → optional BasicAuth → optional TLS), and a WebSocket handler that bridges a Master (WebSocket) and a Slave (PTY/command) via the WebTTY core.
  • WebTTY protocol: simple prefix-based binary messages over WebSocket — client→server: Input '1', Ping '2', ResizeTerminal '3', SetEncoding '4'; server→client: Output '1', Pong '2', SetWindowTitle '3', SetReconnect '5'. All data is base64-encoded to avoid WebSocket text-frame issues.
  • PTY layer: each connection spawns a fresh process via exec.Command + creack/pty (TERM=xterm-256color). Graceful shutdown sends a signal (default SIGHUP), waits closeTimeout (default 10s), then SIGKILL.
  • Connection controls: --once (single connection), --max-connection, --timeout.
  • Security layers: --tls / --tls-ca-crt (client certs), --credential (Basic Auth), --random-url (obscured path), --permit-write (read-only by default), --ws-origin (origin whitelist). WebSocket auth validates an AuthToken against the configured credential.
  • Multi-user modes:
  • 1. Isolated processes (default) — every connection calls Factory.New(), so each user gets an independent process. Best for stateless commands (top, htop). 2. Shared session (tmux/screen) — gotty tmux new -A -s shared-session top or gotty screen -x shared-session; all users see the same session and each other's input. 3. Docker isolation — gotty -w docker run -it --rm ubuntu bash gives each user a disposable container.
  • Deployment recipes:
  • Teaching demo (read-only broadcast): run a detached tmux session and share it; add TLS with --tls-crt/--tls-key.
  • Pair programming: gotty -w -c team:shared123 tmux attach -t pair-programming (shared cursor; consider --max-connection).
  • Per-user sandbox: wrapper script reading HTTP_X_FORWARDED_USER, launching docker run -it --rm ... ubuntu:22.04 bash with a per-user volume.
  • Production: Nginx reverse proxy with WebSocket upgrade headers and least_conn balancing across multiple GoTTY instances.
  • Extensibility: implement the server.Slave interface (Read, Write, Close, ResizeTerminal, WindowTitleVariables) to add backends such as SSH, Docker, or Kubernetes.
  • Security best practices: never expose gotty -w bash; restrict to specific safe commands; bind to 127.0.0.1 and terminate TLS at a proxy; rotate credentials via environment variables; rely on built-in access logs for auditing.
  • Performance & monitoring

    Connection limits are enforced in server/handlers.go (rejecting when above MaxConnection). Recommended caps: 10 for dev; tune per host resources in production (one process per connection). A simple monitor loops over pgrep -c gotty, counts /dev/pts/ entries, and logs uptime every 30 seconds.

    Conclusion

    GoTTY's design balances simplicity (single static binary), isolation (one process per connection by default), flexibility (sharing via tmux/screen, sandboxing via Docker), and extensibility (clean Slave interface). The key to multi-user use is understanding the default isolation model: sharing requires external tools; stronger isolation requires containers.

    References:

  • Official repo: https://github.com/sorenisanerd/gotty
  • PTY library: github.com/creack/pty
  • WebSocket library: github.com/gorilla/websocket

Tags

#gotty#web-terminal#go#websocket#tmux#docker#multi-user#architecture

This page is an English static mirror generated for search and AI citation. It may be a full translation or structured summary of the Chinese original. Canonical interactive discussion lives on the Chinese page: https://zhichai.net/topic/177169639