From e4117cd3d50a0d298798bc403761421ac6c204f9 Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 22 May 2026 13:02:23 -0400 Subject: [PATCH 1/8] fix: remove venv volume mount conflicting with entrypoint.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The volume mount at /mnt/HoardingCow_docker_data/Hermes/venv overrides the container's built .venv with an empty or stale host directory, causing entrypoint.sh line 62 to fail on 'source .venv/bin/activate' (set -e). The Docker image already builds a complete venv — no need to persist it. --- ai/compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/ai/compose.yml b/ai/compose.yml index ca5f181..3126c2b 100755 --- a/ai/compose.yml +++ b/ai/compose.yml @@ -61,8 +61,6 @@ services: - /mnt/HoardingCow_docker_data/Syncthing/telos-ro:/opt/data/telos-ro:ro # Syncthing-shared inbox — write tasks here, they sync to user's laptop - /mnt/HoardingCow_docker_data/Syncthing/telos-rw:/opt/data/telos-rw:rw - # Persist Python venv across container recreation (Matrix bridge deps, etc.) - - /mnt/HoardingCow_docker_data/Hermes/venv:/opt/hermes/.venv devices: - /dev/kfd:/dev/kfd - /dev/dri:/dev/dri -- 2.49.1 From bce336c4fd1bd4f6c12d38df186e6515e2c88467 Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 22 May 2026 13:04:43 -0400 Subject: [PATCH 2/8] feat: bake Matrix bridge deps into Docker image instead of volume mount - Add libolm-dev system dep (required by mautrix[encryption]) - Add mautrix[encryption] + openai pip packages to build - These were previously installed inline at container startup and persisted via the fragile venv volume mount (now removed) --- ai/hermes/Dockerfile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ai/hermes/Dockerfile b/ai/hermes/Dockerfile index c3a76fa..253b9b7 100644 --- a/ai/hermes/Dockerfile +++ b/ai/hermes/Dockerfile @@ -34,6 +34,7 @@ USER root RUN apt-get update && \ apt-get install -y --no-install-recommends \ libportaudio2 ca-certificates poppler-utils imagemagick \ + libolm-dev \ texlive-latex-base texlive-latex-extra texlive-fonts-recommended \ texlive-xetex texlive-science \ qemu-user-static binfmt-support emacs-nox && \ @@ -42,6 +43,12 @@ RUN apt-get update && \ # ---------- UV ---------- COPY --chmod=0755 --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/ +# ---------- Matrix bridge + extra pip deps ---------- +# Previously installed inline at container startup and persisted via volume mount. +# Now baked into the image so the fragile venv volume mount can be removed. +RUN . /opt/hermes/.venv/bin/activate && \ + uv pip install --no-cache-dir 'mautrix[encryption]' openai + # ---------- Piper TTS ---------- RUN . /opt/hermes/.venv/bin/activate && \ uv pip install --no-cache-dir piper-tts sounddevice numpy && \ -- 2.49.1 From 45a224eb7fad685c7e9abee9b1a95d3514136e38 Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 22 May 2026 13:22:58 -0400 Subject: [PATCH 3/8] fix: add missing command: gateway run to hermes service Without this, is empty and entrypoint.sh runs bare 'hermes' which defaults to interactive chat mode. With a non-TTY stdin this exits immediately with prompt_toolkit's 'Input is not a terminal' warning, causing a container restart loop. The profile gateways (run-multi-gateways.sh) were unaffected because the script passes 'gateway run' explicitly. --- ai/compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ai/compose.yml b/ai/compose.yml index 3126c2b..bc0cd4f 100755 --- a/ai/compose.yml +++ b/ai/compose.yml @@ -35,6 +35,8 @@ services: "bash /opt/data/hermes-tools/install.sh && bash /opt/data/hermes-tools/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 environment: - OLLAMA_HOST=http://ollama:11434 - HERMES_DASHBOARD=1 -- 2.49.1 From d8a1ebcd96a204978bbfb027e4ea2cd867ed8763 Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 22 May 2026 13:22:58 -0400 Subject: [PATCH 4/8] fix: add missing command: gateway run to hermes service Without this, is empty and entrypoint.sh runs bare 'hermes' which defaults to interactive chat mode. With a non-TTY stdin this exits immediately with prompt_toolkit's 'Input is not a terminal' warning, causing a container restart loop. The profile gateways (run-multi-gateways.sh) were unaffected because the script passes 'gateway run' explicitly. --- ai/compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ai/compose.yml b/ai/compose.yml index 3126c2b..bc0cd4f 100755 --- a/ai/compose.yml +++ b/ai/compose.yml @@ -35,6 +35,8 @@ services: "bash /opt/data/hermes-tools/install.sh && bash /opt/data/hermes-tools/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 environment: - OLLAMA_HOST=http://ollama:11434 - HERMES_DASHBOARD=1 -- 2.49.1 From 146add2a64e077db5be1f735a9e332fbc6045c30 Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 22 May 2026 13:34:12 -0400 Subject: [PATCH 5/8] fix: use full hermes path and gosu in multi-gateway launcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use /opt/hermes/.venv/bin/hermes (full path) — not on PATH before entrypoint.sh sources the venv - Wrap with gosu hermes to avoid root guard in gateway run - Add error check if hermes binary doesn't exist --- run-multi-gateways.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100755 run-multi-gateways.sh diff --git a/run-multi-gateways.sh b/run-multi-gateways.sh new file mode 100755 index 0000000..cedf365 --- /dev/null +++ b/run-multi-gateways.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Multi-gateway launcher for HERMES_PROFILES env var. +# Reads comma-separated profile names, spawns one gateway per profile. +# Designed to run before the main entrypoint — gateways run in background. +set -e + +if [ -z "${HERMES_PROFILES}" ]; then + echo "HERMES_PROFILES not set — skipping multi-gateway launch" + exit 0 +fi + +# Source venv to make 'hermes' available (entrypoint.sh sources it later, +# but we need it NOW for the background gateways) +HERMES_BIN="/opt/hermes/.venv/bin/hermes" +if [ ! -x "$HERMES_BIN" ]; then + echo "ERROR: hermes binary not found at $HERMES_BIN" + exit 1 +fi + +mkdir -p /opt/data/logs + +IFS=',' read -ra PROFILES <<< "${HERMES_PROFILES}" +for profile in "${PROFILES[@]}"; do + profile="$(echo "${profile}" | xargs)" # trim whitespace + [ -z "${profile}" ] && continue + + echo "Starting gateway for profile: ${profile}" + API_SERVER_ENABLED=false \ + nohup gosu hermes "$HERMES_BIN" --profile "${profile}" gateway run \ + >> "/opt/data/logs/gateway-${profile}.log" 2>&1 & +done + +echo "All gateways launched: ${HERMES_PROFILES}" -- 2.49.1 From 645d519030a9a78ddac75ee6e224d1948b67dec6 Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 22 May 2026 13:52:05 -0400 Subject: [PATCH 6/8] fix: use env to force API_SERVER_ENABLED=false in multi-gateway launcher Shell prefix didn't work with nohup+gosu chain - Docker compose env var API_SERVER_ENABLED=true leaked through. Using 'env' command guarantees the override is in the child process env. --- run-multi-gateways.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/run-multi-gateways.sh b/run-multi-gateways.sh index cedf365..26db250 100755 --- a/run-multi-gateways.sh +++ b/run-multi-gateways.sh @@ -25,8 +25,7 @@ for profile in "${PROFILES[@]}"; do [ -z "${profile}" ] && continue echo "Starting gateway for profile: ${profile}" - API_SERVER_ENABLED=false \ - nohup gosu hermes "$HERMES_BIN" --profile "${profile}" gateway run \ + nohup env API_SERVER_ENABLED=false gosu hermes "$HERMES_BIN" --profile "${profile}" gateway run \ >> "/opt/data/logs/gateway-${profile}.log" 2>&1 & done -- 2.49.1 From e8075fb71bf317878ef52d53b3e825e2b4e3bae9 Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 22 May 2026 13:53:53 -0400 Subject: [PATCH 7/8] fix: also clear API_SERVER_KEY for profile gateways Line 1521 in gateway/config.py: if api_server_enabled or api_server_key: The compose.yml sets API_SERVER_KEY=hermes_local_key, which was enough to enable the API server even with API_SERVER_ENABLED=false. --- run-multi-gateways.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-multi-gateways.sh b/run-multi-gateways.sh index 26db250..f23ac78 100755 --- a/run-multi-gateways.sh +++ b/run-multi-gateways.sh @@ -25,7 +25,7 @@ for profile in "${PROFILES[@]}"; do [ -z "${profile}" ] && continue echo "Starting gateway for profile: ${profile}" - nohup env API_SERVER_ENABLED=false gosu hermes "$HERMES_BIN" --profile "${profile}" gateway run \ + nohup env API_SERVER_ENABLED=false API_SERVER_KEY= gosu hermes "$HERMES_BIN" --profile "${profile}" gateway run \ >> "/opt/data/logs/gateway-${profile}.log" 2>&1 & done -- 2.49.1 From c1cd9d31e9fcd753f6d0c0f07b114f33eb212ebe Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 22 May 2026 21:37:01 -0400 Subject: [PATCH 8/8] fix: move run-multi-gateways.sh into ai/hermes/ and bake into image --- ai/compose.yml | 2 +- ai/hermes/Dockerfile | 4 ++++ run-multi-gateways.sh => ai/hermes/run-multi-gateways.sh | 0 3 files changed, 5 insertions(+), 1 deletion(-) rename run-multi-gateways.sh => ai/hermes/run-multi-gateways.sh (100%) diff --git a/ai/compose.yml b/ai/compose.yml index bc0cd4f..89dceca 100755 --- a/ai/compose.yml +++ b/ai/compose.yml @@ -32,7 +32,7 @@ services: - default container_name: hermes entrypoint: ["/bin/bash", "-c", - "bash /opt/data/hermes-tools/install.sh && bash /opt/data/hermes-tools/run-multi-gateways.sh && exec /usr/bin/tini -g -- /opt/hermes/docker/entrypoint.sh \"$@\"", + "bash /opt/data/hermes-tools/install.sh && 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 diff --git a/ai/hermes/Dockerfile b/ai/hermes/Dockerfile index 253b9b7..dd044f9 100644 --- a/ai/hermes/Dockerfile +++ b/ai/hermes/Dockerfile @@ -76,6 +76,10 @@ os.remove(tgz) print('himalaya v1.2.0 installed') PYEOF +# ---------- Install multi-gateway launcher ---------- +# Launches one gateway process per profile (HERMES_PROFILES env var) +COPY --chmod=0755 run-multi-gateways.sh /usr/local/bin/run-multi-gateways.sh + # ---------- Runtime ---------- USER hermes ENV HERMES_HOME=/opt/data diff --git a/run-multi-gateways.sh b/ai/hermes/run-multi-gateways.sh similarity index 100% rename from run-multi-gateways.sh rename to ai/hermes/run-multi-gateways.sh -- 2.49.1