Karan Sharma

A Web Terminal for My Homelab with ttyd + tmux

3 minutes (690 words)

I wanted a browser terminal at terminal.mrkaran.dev that works from laptop, tablet, and phone without special client setup.

The stack that works cleanly for this is ttyd + tmux.

Architecture#

Browser -> Caddy -> ttyd -> nsenter -> su - karan -> tmux(main)

Two decisions matter most:

  1. ttyd handles terminal-over-websocket behavior well.
  2. -m 1 enforces a single active client, which avoids cross-tab resize contention.

Docker Compose (current)#

services:
  webterm:
    image: tsl0922/ttyd
    container_name: webterm
    restart: unless-stopped
    command: >
      ttyd
        -W
        -p 8080
        -m 1
        nsenter
        -t 1
        -m -u -i -p
        --
        su - karan -c
        "tmux new-session -A -s main"
    privileged: true
    pid: "host"
    networks:
      - public_proxy

Why each flag matters:

Caddy#

terminal.mrkaran.dev reverse proxies to webterm:8080 with TLS via Cloudflare DNS challenge. Because ttyd uses WebSockets heavily, reverse proxy support for upgrades is essential.

tmux profile for agentic workflows#

I tuned tmux for long-running agent sessions, not just manual shell use.

Long-run defaults#

Better operational visibility#

Keybinds I actually use#

Prefix: Ctrl-b

Copy/paste that is not annoying#

This was a big pain point, so I added both workflows:

  1. Browser-native copy

    • Ctrl-b m to turn tmux mouse off
    • drag-select + browser copy shortcut
    • Ctrl-b m to turn tmux mouse back on
  2. tmux copy mode

    • Ctrl-b [ enters copy mode and shows COPY MODE ON
    • v select, y copy (shows Copied selection)
    • q or Esc exits (shows COPY MODE OFF)

On mobile, ttyd’s top-left menu (special keys) makes prefix navigation workable.

Security model#

This is tailnet-only behind Tailscale. No public exposure.

Still, the container has privileged: true and pid: host, which is a strong trust boundary. If you expose anything like this publicly, add auth in front and treat it as high-risk infrastructure.

Result#

Web terminal in the browser

The terminal is now boring in the best way: stable, predictable, and fast to reach from any device.

Tags: #Homelab #Devops #tmux #ttyd