zotero.fhirworx.io rendered a blank desktop: KDE+Zotero draw on Xvfb :20, but kasmvnc serves :21, and the kasmxproxy mirror that bridges them never started. The stock kasmvnc-entrypoint.sh blocks on `until [ -S /tmp/.X11-unix/X21 ]` (a filesystem socket path) while entrypoint.sh's concurrent `rm -rf /tmp/.X*` unlinks it — Xvnc keeps its fd + abstract socket open and serves a blank :21 forever. A startup race, hence the intermittent "doesn't open" with every process reporting healthy. - kasmxproxy-guard.sh: supervised watchdog that probes :20/:21 via xdpyinfo (not the racy socket file) and (re)launches kasmxproxy, self-healing if it dies. Emits structured `zotero_event=` logs to container stdout + a heartbeat file. - zotero-healthcheck.sh + compose healthcheck: detect the real failure mode (bridge down / :21 unreachable / KDE dead / stale heartbeat) that container/nginx/Xvnc liveness all miss. - promtail: extract zotero_event into a Loki label. - Grafana: Zotero Desktop dashboard + alert on sustained bridge failure. - otel-cli baked in; OTLP tracing dormant by default (enabling it requires attaching zotero to the observability network — documented opt-in, left off to preserve gateway-only isolation). Verified live: guard self-heals on kasmxproxy kill; healthcheck passes healthy / fails on stale heartbeat.
21 lines
736 B
Plaintext
21 lines
736 B
Plaintext
; Supervised watchdog that keeps the KDE desktop (:20) mirrored onto the
|
|
; KasmVNC display (:21). Fixes the startup race where the stock
|
|
; kasmvnc-entrypoint.sh never launches kasmxproxy. See kasmxproxy-guard.sh.
|
|
;
|
|
; priority 25 > kasmvnc's 20 so we start after Xvnc; autorestart keeps the
|
|
; watchdog itself alive. Logs go to /dev/fd/1 (the container's stdout) so
|
|
; promtail -> Loki picks them up — supervisord child logs default to files
|
|
; under /tmp that never reach `docker logs`.
|
|
[program:kasmxproxy-guard]
|
|
command=/usr/local/bin/kasmxproxy-guard.sh
|
|
autostart=true
|
|
autorestart=true
|
|
startsecs=3
|
|
startretries=9999
|
|
stopasgroup=true
|
|
killasgroup=true
|
|
priority=25
|
|
stdout_logfile=/dev/fd/1
|
|
stdout_logfile_maxbytes=0
|
|
redirect_stderr=true
|