web-terminal-server
A small, generic web terminal: it runs a configured command in a PTY and serves the @cplieger/web-terminal-ui front end over HTTP + WebSocket, built on the github.com/cplieger/web-terminal-engine engine. A native-touch terminal in the browser for any command, on phone and desktop alike.
Published as a multi-arch (amd64 + arm64) container image on GHCR (ghcr.io/cplieger/web-terminal-server) and Docker Hub (cplieger/web-terminal-server).
⚠️ Security: this is a remote shell
Anyone who can reach the server and pass auth (if configured) gets an interactive process running SESSIONCMD with this server's privileges. Treat it like exposing SSH.
- The binary binds 127.0.0.1 by default. Reachable only from the same
host until you change LISTENADDR.
- The container image binds :7681 (it has to, to be reachable via a
published port) and so is unauthenticated and network-exposed by default. Before exposing it beyond a trusted host, do one of:
- set AUTHPASSWORD (enables HTTP Basic auth on every route, including the
WebSocket handshake), and/or
- front it with an authenticating reverse proxy (Caddy + forward-auth,
oauth2-proxy, Authentik, …), and/or
- keep the published port bound to loopback / a private network only.
- The server logs a loud warning at startup when it is listening on a
non-loopback address without AUTHPASSWORD set.
- Each session's recent output (200 lines) is kept in the browser's localStorage by default so a
reloaded tab does not refill over the wire. It is readable from that browser without passing AUTHPASSWORD and outlives the tab; set PERSISTSCROLLBACK=false on a shared device or where storing command output at rest is unacceptable. See Persisted scrollback.
- DNS rebinding reaches even loopback binds through your own browser: an