Adds a digest-pinned headless-shell Chrome DevTools Protocol daemon as a boot-persistent quadlet unit (chrome-devtools-protocol.container). The entrypoint override drops the image's socat front so the CDP endpoint binds loopback-only on 127.0.0.1:9222 in the host network namespace; only the two host-network consumers (Signal gateway, webui server) can drive it. hermes-webui flips Network=dankclaw_default -> Network=host so its agent process shares the daemon's namespace (0.0.0.0:8787 bind is LAN-facing as before; no exposure change). deploy_hermes installs the new unit and starts it if inactive without restarting in-flight browser sessions.
56 lines
2.3 KiB
INI
56 lines
2.3 KiB
INI
# Quadlet unit: Hermex webui (Hermex) container (rootless, boot-persistent).
|
|
#
|
|
# Install path on dankclaw: ~/.config/containers/systemd/hermes-webui.container
|
|
# Unit name: hermes-webui.service (container name: hermes-webui)
|
|
#
|
|
# Runs the open-source hermes-webui (github.com/nesquena/hermes-webui) in
|
|
# foreground mode: bootstrap.py creates .venv inside the mounted checkout,
|
|
# installs WebUI + agent deps, then execs server.py as a single foreground
|
|
# process. It reads HERMES_HOME=/data, so it drives the SAME agent state
|
|
# (memory, skills, sessions) as the gateway container.
|
|
#
|
|
# Host networking on purpose: the agent's chrome-devtools MCP client spawns
|
|
# npx chrome-devtools-mcp with --browserUrl=http://127.0.0.1:9222, and the CDP
|
|
# daemon binds loopback-only in the host network namespace (see
|
|
# chrome-devtools-protocol.container). Only processes sharing that namespace
|
|
# can drive the browser; a bridge-network client could not reach it at all.
|
|
# The server therefore listens on 0.0.0.0:8787 of the host netns (LAN-facing as
|
|
# before); access control is the password gate, and the SSH tunnel
|
|
# (phone -> Dankclaw:22) remains the sole off-network ingress path.
|
|
|
|
[Unit]
|
|
Description=Hermes webui (Hermex) container
|
|
|
|
[Container]
|
|
ContainerName=hermes-webui
|
|
Image=localhost/hermes-agent:latest
|
|
Pull=never
|
|
Network=host
|
|
EnvironmentFile=/home/dank/serverAppConfigs/dankclaw/.env
|
|
Environment=HERMES_WEBUI_HOST=0.0.0.0
|
|
Environment=HERMES_WEBUI_PORT=8787
|
|
Environment=HERMES_WEBUI_PASSWORD=${HERMES_WEBUI_PASSWORD}
|
|
# Headless host: never show the first-run wizard (a profile already
|
|
# exists in /data from the gateway).
|
|
Environment=HERMES_WEBUI_SKIP_ONBOARDING=1
|
|
Volume=/home/dank/hermes-data:/data
|
|
Volume=/home/dank/hermes-webui:/webui
|
|
Exec=python3 /webui/bootstrap.py --foreground
|
|
# JSON exec form on purpose: this quadlet generator joins a bare HealthCmd
|
|
# into ONE argv element with \x20 escapes and then shell-executes it — the
|
|
# python one-liner's quoting would be mangled. A JSON array is passed through
|
|
# verbatim. Start period covers first-boot pip installs into /webui/.venv.
|
|
HealthCmd=["python3","-c","import urllib.request;urllib.request.urlopen('http://127.0.0.1:8787/health')"]
|
|
HealthInterval=30s
|
|
HealthTimeout=10s
|
|
HealthRetries=5
|
|
HealthStartPeriod=600s
|
|
|
|
[Service]
|
|
Restart=always
|
|
RestartSec=5
|
|
EnvironmentFile=/home/dank/serverAppConfigs/dankclaw/.env
|
|
|
|
[Install]
|
|
WantedBy=default.target
|