Files
clide/docs/web-deployment.md
T
jpmschweitzerandClaude Opus 4.6 dba0e4805f Add web deployment layer and docs for browser-based setup
Pull ttyd/zellij/clide-launcher scripts into deploy/ so the web access
layer lives with the project. Zellij is configured in locked mode with a
bare layout so it only provides session persistence without intercepting
keys or showing UI. Remove Ctrl+G goto-line binding from Clide to avoid
conflict with Zellij's unlock key.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:00:20 +01:00

4.5 KiB

Web Deployment

Clide runs in a browser via a three-layer stack:

Browser (code.schweitz.net)
 └─ ttyd (web terminal server, port 8888)
     └─ zellij (session persistence only)
         └─ clide (Textual TUI)
             └─ claude code (embedded PTY)

Components

Layer Purpose Config
ttyd Serves terminal over WebSocket systemd service on port 8888
zellij Session reconnection (detach/reattach) Locked mode, bare layout, no UI
clide TUI IDE wrapper around Claude Code Zellij's default shell

Installation

From the clide project root:

sudo bash deploy/install-clide-web.sh

This installs:

  1. ttyd binary to /usr/local/bin/
  2. zellij binary to /usr/local/bin/
  3. clide-launcher script to /usr/local/bin/
  4. Zellij config to ~/.config/zellij/ (locked mode + bare layout)
  5. clide-web.service systemd unit
  6. Enables and starts the service

Reverse Proxy

For external access, configure your reverse proxy (e.g., Nginx Proxy Manager) to:

  • Proxy code.schweitz.netlocalhost:8888
  • Enable WebSocket support (required for ttyd)

Architecture

ttyd

Web terminal server. Runs clide-launcher for each browser connection.

Service: /etc/systemd/system/clide-web.service

Key flags:

  • -p 8888 — port
  • -W — writable (allows input)
  • -a — allows URL arguments (passes ?project=X to the launcher)
  • -t fontSize=14 — terminal font size

clide-launcher

Entry point script at /usr/local/bin/clide-launcher. Handles:

  1. Project selection — parses ?project=NAME from the URL
  2. Session management — creates or reattaches to a Zellij session named clide-<project>
  3. Fallback UI — shows a project selector if no project specified

URL patterns:

  • code.schweitz.net — shows project selector
  • code.schweitz.net?project=clide — opens/attaches to the clide project

Zellij

Used only for session persistence (reconnecting after browser close/refresh). All UI features are disabled.

Config: deploy/zellij/config.kdl

Key settings:

  • default_mode "locked" — all keys pass through to Clide except Ctrl+G
  • default_layout "bare" — no tab bar, no status bar
  • pane_frames false — no pane borders
  • default_shell — points to the clide binary
  • show_startup_tips false

Layout: deploy/zellij/bare.kdl — single pane, zero chrome.

Keybinding Layering

Since the stack is deeply nested, keybindings are carefully layered:

Key Layer Action
Ctrl+G Zellij Unlock Zellij (only key Zellij captures in locked mode)
Ctrl+Q Clide Quit Clide
Ctrl+B Clide Toggle sidebar
Ctrl+P Clide Quick open
Ctrl+S Clide Save file
All others Clide → Claude Pass through to Clide, then to Claude Code

To detach a session (e.g., before service restart):

  1. Ctrl+G — unlock Zellij
  2. Ctrl+O — session mode
  3. d — detach

Or just close the browser tab — Zellij detaches automatically.

Operations

Service Management

# Status
systemctl status clide-web

# Restart (disconnects all sessions)
sudo systemctl restart clide-web

# Logs
journalctl -u clide-web -f

Session Management

# List sessions
zellij list-sessions

# Kill stuck sessions
zellij delete-all-sessions --force --yes

# Clear serialized session cache (if ghost sessions persist)
rm -rf ~/.cache/zellij/*/session_info/clide-*

Troubleshooting

Service stuck in deactivating: A child process (usually claude) didn't respond to SIGTERM.

sudo systemctl kill -s SIGKILL clide-web
sudo systemctl start clide-web

Old sessions ignore config changes: Zellij serializes sessions. Delete them and restart:

zellij delete-all-sessions --force --yes
rm -rf ~/.cache/zellij/*/session_info/clide-*
sudo systemctl restart clide-web

Keys not reaching Clide: Zellij may be in normal mode. Press Ctrl+G to toggle back to locked mode. The status bar being visible is a sign you're unlocked (bare layout hides it in locked mode).

Files

deploy/
├── install-clide-web.sh    # Installation script (run with sudo)
├── clide-launcher           # Session launcher (ttyd → zellij → clide)
├── clide-web.service        # systemd unit file
└── zellij/
    ├── config.kdl           # Zellij config (locked mode, no UI)
    └── bare.kdl             # Bare layout (single pane, no chrome)