# Quadlet unit: Hermes agent gateway (rootless, boot-persistent). # # Install path on dankclaw: ~/.config/containers/systemd/hermes.container # Unit name: hermes.service (container name: hermes) # # The messaging gateway (Signal adapter -> the host signal-cli daemon). The # image's default s6 entrypoint would run the interactive TUI, which exits # without a TTY; Exec= below replaces it with the headless gateway command, # spliced by the v1 quadlet generator as trailing args after the image ref # (same splice pattern proven live on authentik-worker). The gateway drops to # the unprivileged hermes user (uid 10000) at runtime; /data is world-writable # on purpose so that unmapped uid can write agent.log and its state there. # # Host networking: the adapter dials the signal-cli daemon, a HOST process # listening on :8080. The compose era dialed the host LAN IP from a bridge # network, where only DNAT'd published ports accept connections to that # address — un-forwarded host ports refuse instantly (verified live # 2026-08-30). A host-network client dials 127.0.0.1:8080 with no such # dependency, and the gateway publishes nothing inbound. [Unit] Description=Hermes agent gateway container After=network-online.target Wants=network-online.target [Container] Network=host Image=localhost/hermes-agent:latest Pull=never EnvironmentFile=/home/dank/serverAppConfigs/dankclaw/.env Environment=HERMES_DATA_DIR=/data Environment=HERMES_HOME=/data Environment=SIGNAL_HTTP_URL=http://127.0.0.1:8080 Environment=SIGNAL_ACCOUNT=${SIGNAL_ACCOUNT} Environment=SIGNAL_ALLOWED_USERS=${SIGNAL_ALLOWED_USERS} Volume=/home/dank/Containers/hermes/data:/data Exec=bash -c 'hermes gateway run --force -v' [Service] Restart=always RestartSec=5 EnvironmentFile=/home/dank/serverAppConfigs/dankclaw/.env [Install] WantedBy=default.target