Skip to content

[Bug]: main-wrapper.sh drops HERMES_HOME env var when launching gateway via s6-setuidgid #33004

@chenli90s

Description

@chenli90s

Bug Description

When running the nousresearch/hermes-agent Docker image with -v ~/.hermes:/opt/data, the gateway process starts without HERMES_HOME in its environment. This causes get_hermes_home() to fall back to ~/.hermes (resolved as /opt/data/.hermes for the hermes user), creating a nested .hermes/ directory inside the mounted volume. User configuration placed in the top-level .env and config.yaml is silently ignored by the gateway.

Steps to Reproduce

  1. Start the container with a mounted volume:
    docker run -d --name hermes \
      -v ~/.hermes:/opt/data \
      nousresearch/hermes-agent gateway run
  2. Set GATEWAY_ALLOW_ALL_USERS=true in the host's ~/.hermes/.env
  3. Check the gateway log:
    docker exec hermes grep "No user allowlists" /opt/data/.hermes/logs/gateway.log
  4. Note the warning persists despite the env var being set

Expected Behavior

  • Gateway should load config from /opt/data/.env and /opt/data/config.yaml
  • GATEWAY_ALLOW_ALL_USERS=true in ~/.hermes/.env should be respected
  • Logs should go to /opt/data/logs/gateway.log
  • No duplicate .hermes/ directory should be created inside the mounted volume

Actual Behavior

  • Gateway writes logs to /opt/data/.hermes/logs/gateway.log instead of /opt/data/logs/gateway.log
  • Environment variables in /opt/data/.env (e.g., GATEWAY_ALLOW_ALL_USERS=true) are not seen by the gateway
  • A duplicate .hermes/ data directory is silently created inside the mounted volume
  • The warning "No user allowlists configured" appears despite GATEWAY_ALLOW_ALL_USERS=true being set
  • docker exec CLI sessions correctly inherit HERMES_HOME=/opt/data, but the gateway (Docker CMD) does not
  • The two data directories diverge independently, making diagnosis extremely difficult

Affected Component

  • Configuration (config.yaml, .env, hermes setup)
  • Gateway (Telegram/Discord/Slack/WhatsApp)

Messaging Platform

  • weixin

Operating System

Docker container (windows)

Hermes Version

Latest (nousresearch/hermes-agent with s6-overlay)

Additional Logs / Traceback

  • Gateway logs appear at /opt/data/.hermes/logs/gateway.log (wrong path)
  • docker exec <container> cat /proc/<gateway_pid>/environ | tr '\0' '\n' | grep HERMES_HOME returns nothing

Root Cause Analysis

The container uses s6-overlay for process supervision. The Docker CMD runs as the "main program" (not an s6-supervised service), so it does NOT go through the with-contenv mechanism that loads container environment variables into service processes.

The startup chain is:

rc.init → main-wrapper.sh → exec s6-setuidgid hermes → hermes gateway run

main-wrapper.sh sources the venv activate script (/opt/hermes/.venv/bin/activate), which sets PATH and VIRTUAL_ENV but does not set HERMES_HOME. When exec s6-setuidgid hermes performs the privilege drop to the hermes user, the HERMES_HOME variable from the container environment (/run/s6/container_environment/HERMES_HOME) is not propagated.

Docker's -e HERMES_HOME=/opt/data writes to /run/s6/container_environment/, which is only loaded by s6-supervised services via with-contenv. The main program (Docker CMD) does not pick them up.

Proposed Fix

In /opt/hermes/docker/main-wrapper.sh, explicitly export HERMES_HOME before the exec s6-setuidgid call:

 cd /opt/data
 . /opt/hermes/.venv/bin/activate

+# Explicitly propagate container environment variables through s6-setuidgid.
+# In s6-overlay, the Docker CMD runs outside the with-contenv mechanism, so
+# container env vars from /run/s6/container_environment/ are NOT inherited.
+_HERMES_HOME="${HERMES_HOME:-/opt/data}"
+export HERMES_HOME="$_HERMES_HOME"
+export PATH VIRTUAL_ENV
+
 if [ $# -eq 0 ]; then
     exec s6-setuidgid hermes hermes
 fi

This ensures the gateway process inherits HERMES_HOME regardless of how it was launched.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existsarea/configConfig system, migrations, profilesarea/dockerDocker image, Compose, packagingcomp/gatewayGateway runner, session dispatch, deliveryduplicateThis issue or pull request already existstype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions