docs(tmux-host): documentar gotcha de reinicio completo del NAS (2026-09-19)
Tras un corte de luz real, la sesion tmux "lab" se recreaba sola pero Claude Code nunca arrancaba adentro -- distinto al caveat de persistencia de sesion ya documentado (ese es "el proceso muere, el contenedor sigue vivo"; esto es "el host completo se apaga y arranca de cero"). Documenta las dos causas encontradas (claude nunca se lanzaba tras recrear la sesion; riesgo de carrera con el mount de /media/HDD-Storage) y el fix aplicado en scripts/tmux-host/healthcheck.sh. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
e3c27de736
commit
a77a6f2fd0
1 file changed
+57
-3
@@ -230,9 +230,13 @@ falla:
|
||||
contenedor.
|
||||
- **Existencia de la sesión tmux `lab`** (`tmux has-session`): si no
|
||||
existe, **sí se recrea automáticamente** (`tmux new-session -d -s lab
|
||||
-c <WORKDIR>`) — es solo recuperar el propio entorno de trabajo del
|
||||
contenedor, no tocar infraestructura externa, así que es seguro
|
||||
hacerlo sin intervención humana.
|
||||
-c <WORKDIR>`, seguido de `tmux send-keys -t lab claude Enter` — ver
|
||||
gotcha "sesión recreada pero sin Claude Code adentro" más abajo) — es
|
||||
solo recuperar el propio entorno de trabajo del contenedor, no tocar
|
||||
infraestructura externa, así que es seguro hacerlo sin intervención
|
||||
humana. Si `WORKDIR` todavía no está montado (ver gotcha siguiente),
|
||||
no se crea la sesión esa vuelta — se reintenta en el próximo ciclo en
|
||||
vez de crearla mal posicionada.
|
||||
|
||||
Todo evento (chequeo ok, falla de red, sesión recreada) queda en
|
||||
`/DATA/AppData/k3d-lab-v3/tmux-host/logs/health.log` — persistente en
|
||||
@@ -247,6 +251,56 @@ contenedor con `-e HEALTHCHECK_INTERVAL_SEC=60` (solo para pruebas en un
|
||||
contenedor descartable — nunca cambiar esto en el `tmux-host` real sin
|
||||
volver a 1800 después).
|
||||
|
||||
## Gotcha: sesión recreada, pero sin Claude Code adentro (reinicio completo del NAS, 2026-09-19)
|
||||
|
||||
Distinto al caveat de persistencia de sesión de más abajo (ese cubre "el
|
||||
*proceso* muere pero el contenedor sigue vivo" — cerrar la sesión `lab` a
|
||||
mano, o un crash del propio `claude`). Este es otro escenario: **el HOST
|
||||
completo se apaga y vuelve a arrancar desde cero** (corte de luz, no un
|
||||
`docker restart` ordenado) — reordena cuándo arrancan Docker, la red y los
|
||||
montajes de `/DATA`/`/media/HDD-Storage` entre sí, algo que un
|
||||
`docker restart` normal nunca ejercita porque el host ya estaba arriba.
|
||||
|
||||
Tras un corte de luz real, se encontró que el usuario se reconectó a la
|
||||
sesión `lab` y encontró un shell vacío, no Claude Code corriendo. Dos
|
||||
causas distintas, ambas corregidas:
|
||||
|
||||
1. **La sesión tmux SÍ se recreaba sola** (confirmado en `health.log`: el
|
||||
contenedor arrancó y la sesión `lab` quedó recreada en cuestión de
|
||||
segundos), pero `check_tmux_session()` nunca lanzó `claude` adentro —
|
||||
solo garantizaba que existiera el *shell*, no que el proceso de Claude
|
||||
Code estuviera corriendo. El diagrama de arquitectura de este mismo doc
|
||||
siempre mostró `T --> CC["proceso claude"]` como si fuera automático,
|
||||
pero el código nunca lo implementó — el hueco quedó invisible mientras
|
||||
nadie pasó por un reinicio completo real del NAS (en un `docker
|
||||
restart` normal, el `claude` que ya estaba corriendo dentro de la
|
||||
sesión simplemente sigue vivo, porque ahí el proceso *no* muere).
|
||||
**Fix:** `check_tmux_session()` ahora llama `launch_claude_in_session()`
|
||||
(`tmux send-keys -t lab claude Enter`) justo después de crear la sesión
|
||||
— solo cuando la crea de cero, nunca sobre una sesión que ya existe (no
|
||||
se reinyecta `claude` sobre un pane con trabajo en curso).
|
||||
2. **Riesgo de carrera no ejercitado todavía, pero real:** `WORKDIR`
|
||||
(`/DATA/AppData/k3d-lab-v3/lab-cruzcloud`) llega vía el symlink absoluto
|
||||
`/DATA/AppData -> /media/HDD-Storage/AppData` (ver el gotcha del symlink
|
||||
más arriba). Si el storage externo (`/media/HDD-Storage`) tarda en
|
||||
montarse en el host más de lo que tarda Docker en arrancar este
|
||||
contenedor — plausible después de un corte de luz, no de un simple
|
||||
restart —, `mkdir -p "$LOG_DIR"` fallaba en silencio (`set -u` sin
|
||||
`-e`) y ese arranque quedaba *sin ningún rastro* en el log, y
|
||||
`tmux new-session -c "$WORKDIR"` habría creado la sesión mal
|
||||
posicionada (o fallado) contra un directorio que todavía no existe.
|
||||
**Fix:** `wait_for_workdir()` reintenta con backoff (pasos de 5s, hasta
|
||||
`STARTUP_MOUNT_WAIT_MAX_SEC=120` por defecto) a que `WORKDIR` exista
|
||||
antes de tocar el log o crear la sesión; si sigue sin existir pasado
|
||||
ese máximo, se registra el error explícitamente y se reintenta en el
|
||||
siguiente ciclo (30 min) en vez de fallar una sola vez y quedarse así.
|
||||
|
||||
**Validado en vivo:** imagen reconstruida (`tmux-host:test-fix`) y probada
|
||||
en un contenedor descartable aparte (mismos mounts de `/DATA` y
|
||||
`/media/HDD-Storage`, sin tocar el `tmux-host` real) — `docker stop` +
|
||||
`docker start` (arranque desde cero, no `restart`) recreó la sesión `lab`
|
||||
con `claude` corriendo adentro sin intervención manual, en ~1 segundo.
|
||||
|
||||
## Qué sobrevive a qué
|
||||
|
||||
| Evento | ¿Sobrevive la sesión tmux (`lab`)? | ¿Sobrevive el login de Claude Code? |
|
||||
|
||||
Reference in new issue
Block a user