diff --git a/ai/compose.yml b/ai/compose.yml index cd78971..d2bc632 100755 --- a/ai/compose.yml +++ b/ai/compose.yml @@ -6,19 +6,19 @@ services: ssh: - default container_name: hermes - entrypoint: ["/bin/bash", "-c", - "bash /usr/local/bin/run-multi-gateways.sh && exec /usr/bin/tini -g -- /opt/hermes/docker/entrypoint.sh \"$@\"", - "hermes-entrypoint"] restart: always - # Gateway run enables the internal API server on port 8642 - command: gateway run + # Use the image default ENTRYPOINT ["/init", "/opt/hermes/docker/main-wrapper.sh"] + # for proper s6-overlay supervision. The CMD runs our multi-profile launcher + # which spawns per-profile gateways in background, then the default gateway + # in foreground (keeps the container alive). + command: ["/usr/local/bin/start-hermes.sh"] environment: - HERMES_UID=10000 - HERMES_GID=10000 - OLLAMA_HOST=http://ollama:11434 - HERMES_DASHBOARD=1 # Multi-profile: comma-separated list of profiles to run as gateways. - # The entrypoint reads this and starts one gateway per profile. + # start-hermes.sh reads this and starts one gateway per profile. # Add profiles here when they exist on disk (e.g. default,researcher,writer) - HERMES_PROFILES=ashley,claire,finn,matt,paul - API_SERVER_ENABLED=true diff --git a/ai/hermes/Dockerfile b/ai/hermes/Dockerfile index 8cf1e6d..a0481aa 100644 --- a/ai/hermes/Dockerfile +++ b/ai/hermes/Dockerfile @@ -62,6 +62,11 @@ PYEOF # Launches one gateway process per profile (HERMES_PROFILES env var) COPY --chmod=0755 run-multi-gateways.sh /usr/local/bin/run-multi-gateways.sh +# ---------- Install s6-overlay compatible startup script ---------- +# Runs as the CMD via s6-overlay's main-program model. +# Replaces the old bash->tini->entrypoint.sh chain that caused SIGTERM crash loops. +COPY --chmod=0755 start-hermes.sh /usr/local/bin/start-hermes.sh + # ---------- Runtime ---------- USER hermes ENV HERMES_HOME=/opt/data diff --git a/ai/hermes/start-hermes.sh b/ai/hermes/start-hermes.sh new file mode 100644 index 0000000..b6c3787 --- /dev/null +++ b/ai/hermes/start-hermes.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Multi-profile + default gateway launcher — runs as the CMD via s6-overlay. +# +# The image's default ENTRYPOINT ["/init", "/opt/hermes/docker/main-wrapper.sh"] +# starts the s6 supervision tree, then exec's main-wrapper.sh with the CMD args. +# main-wrapper.sh sources the venv, drops to the hermes user via s6-setuidgid, +# and exec's this script. +# +# This script: +# 1. Launches per-profile background gateways (HERMES_PROFILES env var) +# 2. Starts the default gateway in foreground (keeps the container alive) +# +# Replaces the old approach of chaining bash -> tini -g -> deprecated entrypoint.sh +# which bypassed s6-overlay and caused the SIGTERM crash loop. + +set -e + +HERMES_BIN="/opt/hermes/.venv/bin/hermes" + +# --- Multi-profile gateways (background) --- +if [ -n "${HERMES_PROFILES:-}" ]; then + echo "[start-hermes] Launching per-profile gateways: ${HERMES_PROFILES}" + IFS=',' read -ra PROFILES <<< "${HERMES_PROFILES}" + for profile in "${PROFILES[@]}"; do + profile="$(echo "${profile}" | xargs)" # trim whitespace + [ -z "${profile}" ] && continue + echo "[start-hermes] -> background gateway for profile '${profile}'" + # No gosu/s6-setuidgid needed — we're already running as the hermes user + # (main-wrapper.sh drops privileges before exec'ing this script). + nohup "${HERMES_BIN}" --profile "${profile}" gateway run \ + >> "/opt/data/logs/gateway-${profile}.log" 2>&1 & + done + echo "[start-hermes] All profile gateways launched" +fi + +# --- Default gateway (foreground — keeps container alive) --- +echo "[start-hermes] Starting default gateway (foreground)" +exec "${HERMES_BIN}" gateway run