devmaker.net
start/ linux/ claude-code-ssh-sessions-tmux-mosh
Linux

Claude Code per SSH: Sessions mit tmux & mosh sichern

Wer Claude Code auf einem Remote-Server per SSH steuert, kennt das: Die Verbindung reißt ab – mal lässt sich die Session wiederbeleben, mal ist sie tot. Der Trick ist, die Lebensdauer des Prozesses von der Leitung zu entkoppeln. Ich zeige mein Setup aus mosh und tmux, mit dem ein Abbruch nur noch ein Detach statt eines Kills ist – und wie du selbst nach einem echten Crash dort weitermachst, wo du aufgehört hast.

Harry_im_Homelab31 (Portrait)
Harald
2026-06-28 · ~10 Min. Lesezeit
Claude Code per SSH: Sessions mit tmux & mosh sichern

Zwei Arten von Abbruch – nur eine ist ein echtes Problem

Wenn dir beim Betrieb von Claude Code auf einem Remote-Server laufend Sessions wegbrechen, lohnt eine Unterscheidung – denn daraus folgt die Lösung. Es gibt nämlich zwei völlig verschiedene Abbruch-Arten, die man leicht in einen Topf wirft:

  • Die Steuerverbindung reißt ab, der Prozess lebt noch. Das ist der Fall, den du „wiederbeleben“ kannst, wenn du dich erneut auf den Server verbindest.
  • Der claude-Prozess selbst stirbt – etwa durch SIGHUP beim SSH-Abbruch, einen OOM-Kill oder einen Crash. Das ist der „nicht mehr zu retten“-Fall.

Der Kern des Problems: Läuft claude als Kindprozess deiner SSH-Sitzung, nimmt ein Verbindungsabbruch den Prozess gleich mit. Die Lösung ist deshalb immer dieselbe – die Lebensdauer des Prozesses von der Verbindung entkoppeln.

Primärfix: tmux auf dem Server

Lass Claude Code nie direkt in der nackten SSH-Session laufen, sondern immer in tmux (oder screen). Dann ist ein Verbindungsabbruch nur noch ein Detach, kein Kill:

bash
# auf dem Server, idempotent (attached wenn vorhanden, sonst neu):
tmux new -A -s cc
claude

# detachen:          Ctrl-b  d
# nach Abbruch einfach wieder ran:
tmux attach -t cc      # kurz: tmux a -t cc

Damit verschwindet praktisch der gesamte „nicht zu retten“-Fall, denn die allermeisten Abbrüche sind reine Verbindungsabbrüche – der Prozess läuft in tmux unbeeindruckt weiter.

Das setzt natürlich voraus, dass der Server durchläuft. Bei mir ist das ein sparsamer Mini-PC im Homelab – genug RAM für ein paar Docker-Stacks und eben eine dauerhafte tmux-Session, an der claude hängt:

Was tmux eigentlich macht

tmux ist ein Terminal-Multiplexer. Entscheidend ist die Client-Server-Architektur: Beim ersten Aufruf startet im Hintergrund ein tmux-Server als Daemon. Dein Terminal ist nur ein Client. Alle Programme, die du in tmux startest, laufen als Kindprozesse dieses Servers – nicht als Kinder deiner SSH-Session. Reißt SSH ab, verschwindet nur der Client; der Server samt claude läuft weiter, und beim Reconnect attachst du dich neu an den noch lebenden Server.

Die Hierarchie ist Server → Sessions → Windows → Panes: eine Session ist ein abgeschlossener Arbeitsbereich (z. B. einer pro Projekt), ein Window wie ein Tab, ein Pane eine Unterteilung des Fensters.

bash
tmux new -A -s cc        # Session "cc" erstellen ODER attachen, falls vorhanden
tmux ls                  # alle Sessions auflisten
tmux attach -t cc        # an Session "cc" attachen   (kurz: tmux a -t cc)
tmux kill-session -t cc  # Session beenden

Das -A in tmux new -A -s cc bedeutet attach-or-create: Existiert „cc“ schon, wird attached statt mit Fehler abzubrechen. Dadurch ist der Befehl idempotent – derselbe Befehl funktioniert beim ersten Start und bei jedem Reconnect. Genau deshalb nimmt man ihn.

Gesteuert wird tmux von innen über die Prefix-Taste Ctrl-b: erst Prefix drücken, loslassen, dann die Befehlstaste. Die wichtigsten:

  • Ctrl-b d – Detach (abkoppeln, Session läuft weiter)
  • Ctrl-b c – neues Window
  • Ctrl-b n / p – nächstes / vorheriges Window
  • Ctrl-b 0–9 – direkt zu Window-Nummer
  • Ctrl-b % / " – Pane vertikal / horizontal splitten
  • Ctrl-b + Pfeiltaste – zwischen Panes wechseln
  • Ctrl-b z – aktiven Pane zoomen (Toggle)
  • Ctrl-b [ – Scroll-/Copy-Mode (raus mit q)

Gerade der Scroll-Mode ist praktisch, weil ein nacktes Terminal über SSH oft kein brauchbares Scrollback hat – tmux gibt dir hier zurückblätterbare History.

Transport robuster machen: SSH-Keepalive

Bevor wir den Transport ganz austauschen: Zwei Stellschrauben in der SSH-Config reduzieren das Abreißen selbst. ServerAliveInterval schickt regelmäßig ein Lebenszeichen, damit die Verbindung nicht still von Firewalls oder NAT-Timeouts gekappt wird:

bash
# ~/.ssh/config
Host myserver
    ServerAliveInterval 30
    ServerAliveCountMax 6
    TCPKeepAlive yes

mosh: der Transport, der nicht abreißt

mosh (mobile shell) ersetzt SSH als interaktiven Transport und löst genau dessen Schwächen bei instabilen Verbindungen. Die Verbindung wird initial über SSH aufgebaut – Authentifizierung und Start des mosh-server laufen über deine normale SSH-Config und -Keys. Danach wechselt mosh auf ein eigenes UDP-Protokoll; ab dann ist SSH nicht mehr im Spiel.

Drei Eigenschaften machen den Unterschied:

  • Roaming: Die Verbindung hängt an einer Session-ID, nicht am IP/Port-Tupel. Netzwechsel (WLAN → Mobilfunk), Laptop-Schlaf oder eine neue IP übersteht die Session einfach – SSH würde hier hart reißen.
  • Intermittierende Verbindung: Fällt das Netz kurz aus, wartet der mosh-server und synct beim Wiederkommen von selbst, ohne dass du etwas tust.
  • Predictive Echo: mosh synchronisiert den Bildschirmzustand statt eines Byte-Streams und zeigt deine Tastenanschläge lokal spekulativ an. Dadurch fühlt sich selbst eine Verbindung mit hoher Latenz reaktiv an.
bash
mosh user@myserver -- tmux new -A -s cc

Aufgeschlüsselt: mosh user@myserver verbindet per mosh (SSH-Handshake im Hintergrund), -- beendet die mosh-Optionen, und tmux new -A -s cc ist der Befehl, den mosh auf dem Server ausführt. Effekt: ein Befehl von überall – und du landest sofort in deiner persistenten Claude-Session.

Voraussetzungen: mosh muss auf Client und Server installiert sein und braucht die UDP-Ports 60000–61000 erreichbar – also ggf. Firewall bzw. Port-Weiterleitung in der jeweiligen VM/LXC öffnen. Über Tailscale läuft das ohnehin durch. Was mosh nicht kann: eigenes Scrollback (dafür tmux drunter) und Port-Forwarding/X11 – einen Tunnel legst du bei Bedarf separat per ssh -L an.

Recovery für echte Crashes: claude --resume

Fällt der Prozess doch einmal hart aus (OOM, Kernel-Panic, Stromausfall), ist trotzdem nichts verloren: Claude Code schreibt die Session laufend lokal mit. Die Transcripts liegen als JSONL unter ~/.claude/projects/<project>/<session-id>.jsonl, wobei <project> dein Arbeitsverzeichnis mit ersetzten Sonderzeichen ist. Wiederaufnahme:

bash
claude -c                    # letzte Session im aktuellen Verzeichnis (--continue)
claude --resume              # interaktiver Picker
claude --resume <name|id>    # gezielt eine bestimmte Session

--continue (kurz -c) findet automatisch die jüngste Session im aktuellen Arbeitsverzeichnis. Wichtig: aus demselben Verzeichnis starten, in dem die Session begonnen wurde – die ID-Auflösung ist auf das Projektverzeichnis und seine Git-Worktrees beschränkt.

Zwei Gewohnheiten machen das Wiederbeleben zuverlässiger: Sessions benennen (/rename bzw. claude -n "feature-xy"), damit du sie im Picker eindeutig findest statt zwischen kryptischen IDs zu raten. Und beim Resume die Option „aus Zusammenfassung fortsetzen“ nutzen, wenn die Session groß ist – das spart Tokens beim erneuten Einlesen.

Mein Gesamt-Setup

Mein empfohlenes Gesamt-Setup stapelt drei Schichten: mosh → tmux → claude. Damit ist die Steuerverbindung egal geworden, und für den seltenen echten Crash hast du das On-Disk-Transcript plus benannte Sessions als Netz. Ein Befehl, von überall:

bash
mosh user@myserver -- tmux new -A -s cc
# danach in tmux:  claude

mosh sorgt dafür, dass du im Alltag praktisch nie einen Abbruch bemerkst; tmux ist das Sicherheitsnetz für die Fälle, in denen doch mal alles wegbricht. Der Punkt, an dem eine Session „nicht mehr zu retten“ war, sollte damit verschwinden.

Was ich weggelassen habe

  • tmux-resurrect / tmux-continuum sichern den Session-Zustand auf Platte und überstehen sogar einen Server-Reboot. Für einen laufenden claude-Prozess bringt das wenig, weil der Prozess-State nicht serialisierbar ist – da greift stattdessen der --resume-Layer.
  • tmux übersteht keinen Server-Reboot. Disconnect und Logout ja, Neustart nein – dann hilft nur das On-Disk-Transcript.
  • mosh hat Grenzen: kein eigenes Scrollback (deshalb tmux drunter), kein Port-Forwarding/X11. Beides ist im Alltag verschmerzbar.

Fazit

Die eigentliche Erkenntnis ist simpel: Solange claude als Kind der SSH-Session läuft, ist jeder Verbindungsabbruch ein Glücksspiel. Entkoppelt man den Prozess mit tmux und macht den Transport mit mosh robust, wird aus dem „nicht mehr zu retten“ ein folgenloses Detach. Und für den Rest gibt es claude --resume.

// Weitere Empfehlungen

Anzeige · Affiliate-Link – kaufst du darüber, erhalte ich ggf. eine Provision. Für dich ändert sich am Preis nichts.

// verwandte beiträge

> echo "your thoughts" >> claude-code-ssh-sessions-tmux-mosh.responses

Schreibe einen Kommentar

Wird für die Bestätigung benötigt