feat: split-deployment roles (browser-host on LAN + remote bot)

Add JARVIS_ROLE (full|browser|bot) via a run-if-role.sh supervisord guard so
one image serves three layouts. Make Chrome CDP bind configurable (CDP_BIND)
and publishable on the LAN (CDP_PUBLISH_BIND) so a bot on another PC can drive
this host's on-screen Chrome over the internal network (no auth, as requested).
This commit is contained in:
javis-bot
2026-06-15 10:23:55 +09:00
parent bdb012fc7c
commit 1935c1a6bc
4 changed files with 46 additions and 9 deletions

View File

@@ -19,7 +19,7 @@ exec google-chrome \
--disable-translate \
--disable-features=Translate,TranslateUI,InfoBars \
--remote-debugging-port="${CDP_PORT:-9222}" \
--remote-debugging-address=127.0.0.1 \
--remote-debugging-address="${CDP_BIND:-127.0.0.1}" \
--user-data-dir="${CHROME_PROFILE_DIR:-/root/chrome-profile}" \
--password-store=basic --start-maximized \
"${CHROME_START_URL:-about:blank}"

22
docker/run-if-role.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Role guard for split deployments.
#
# run-if-role.sh <roles-csv> <command...>
#
# Runs <command> only when JARVIS_ROLE is one of <roles-csv> (or "full"/unset).
# Otherwise it idles so supervisord keeps the program slot "running" without
# doing any work. This lets ONE image serve three layouts:
#
# JARVIS_ROLE=full (default) everything in one container
# JARVIS_ROLE=browser only the desktop + Chrome + CDP (reused over the LAN)
# JARVIS_ROLE=bot only the bot + bridge + TTS (drives a remote browser
# via CDP_HOST/CDP_PORT)
set -e
want="$1"; shift
role="${JARVIS_ROLE:-full}"
if [ "$role" = "full" ]; then exec "$@"; fi
case ",$want," in
*",$role,"*) exec "$@" ;;
esac
echo "[role-guard] JARVIS_ROLE=$role not in '$want' — idling: $*" >&2
exec sleep infinity

View File

@@ -14,7 +14,7 @@ serverurl=unix:///run/supervisor.sock
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[program:xvnc]
command=/app/docker/run-xvnc.sh
command=/app/docker/run-if-role.sh full,browser /app/docker/run-xvnc.sh
priority=100
autorestart=true
stdout_logfile=/dev/stdout
@@ -23,7 +23,7 @@ stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:pulse]
command=/app/docker/run-pulse.sh
command=/app/docker/run-if-role.sh full,browser /app/docker/run-pulse.sh
priority=150
autorestart=true
stdout_logfile=/dev/stdout
@@ -32,7 +32,7 @@ stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:xfce]
command=/app/docker/run-xfce.sh
command=/app/docker/run-if-role.sh full,browser /app/docker/run-xfce.sh
priority=200
autorestart=true
stdout_logfile=/dev/stdout
@@ -41,7 +41,7 @@ stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:novnc]
command=websockify --web=/usr/share/novnc 6080 localhost:5901
command=/app/docker/run-if-role.sh full,browser websockify --web=/usr/share/novnc 6080 localhost:5901
priority=250
autorestart=true
stdout_logfile=/dev/stdout
@@ -52,7 +52,7 @@ stderr_logfile_maxbytes=0
[program:melo-worker]
; Warm MeloTTS Korean voice (speed 1.5) in its own py3.11 venv. The bridge's
; synthesize() POSTs here; if this is down the bridge falls back to Piper.
command=/opt/melo/bin/python /app/bridge/melo_worker.py
command=/app/docker/run-if-role.sh full,bot /opt/melo/bin/python /app/bridge/melo_worker.py
directory=/app
; HF_HOME points at the dedicated, image-baked melo cache (warmed in
; setup-melo.sh). The brain's whisper_cache volume is mounted over
@@ -73,7 +73,7 @@ stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:bridge]
command=/opt/venv/bin/python -m bridge.server
command=/app/docker/run-if-role.sh full,bot /opt/venv/bin/python -m bridge.server
directory=/app
priority=300
autorestart=true
@@ -83,7 +83,7 @@ stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:chrome]
command=/app/docker/run-chrome.sh
command=/app/docker/run-if-role.sh full,browser /app/docker/run-chrome.sh
priority=350
autorestart=true
stdout_logfile=/dev/stdout
@@ -92,7 +92,7 @@ stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:bot]
command=/app/docker/run-bot.sh
command=/app/docker/run-if-role.sh full,bot /app/docker/run-bot.sh
directory=/app/bot
priority=400
autorestart=true