hermes - 💡(How to fix) Fix [Bug]: `docker/stage2-hook.sh`: `needs_chown` triggers chown on every boot when `HERMES_UID`/`PUID` is set to a non-10000 value, even if volume ownership already matches [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

Additional Logs / Traceback (optional)

Root Cause

Root Cause Analysis (optional)

Fix Action

Fixed

Code Example

docker run -d \
     --name hermes \
     --restart unless-stopped \
     -v ~/.hermes:/opt/data \
     -e PUID=1000 \
     -e PGID=1000 \
     nousresearch/hermes-agent gateway run

---

hermes  | s6-rc: info: service s6rc-oneshot-runner: starting
hermes  | s6-rc: info: service s6rc-oneshot-runner successfully started
hermes  | s6-rc: info: service fix-attrs: starting
hermes  | s6-rc: info: service fix-attrs successfully started
hermes  | s6-rc: info: service legacy-cont-init: starting
hermes  | cont-init: info: running /etc/cont-init.d/01-hermes-setup
hermes  | [stage2] Changing hermes UID to 1000
hermes  | [stage2] Changing hermes GID to 1000
hermes  | [stage2] Fixing ownership of /opt/data (targeted) to hermes (1000)

---

Not applicable. The issue is limited to Docker deployments.

---



---

actual_hermes_uid=$(id -u hermes)      # read AFTER usermod
needs_chown=false
if [ -n "${HERMES_UID:-}" ] && [ "$HERMES_UID" != "10000" ]; then
    needs_chown=true                    # ← always true when PUID is set (startup =)
elif [ "$(stat -c %u "$HERMES_HOME" 2>/dev/null)" != "$actual_hermes_uid" ]; then
    needs_chown=true
fi

---

if [ "$(stat -c %u "$HERMES_HOME" 2>/dev/null)" != "$actual_hermes_uid" ]; then
    needs_chown=true
fi
RAW_BUFFERClick to expand / collapse

Bug Description

When HERMES_UID (or its alias PUID) is set to a value other than the default 10000, the s6-overlay stage2 hook runs chown -R on all Hermes-managed subdirectories on every container start — even after the first boot has already corrected ownership to the remapped UID.

On slow storage (Raspberry Pi SD card) with large data directories (~38K files), this adds 20+ minutes of unnecessary I/O to every docker start or docker restart.

Environment

  • Hermes Agent Docker image (s6-based, v0.15.2+)
  • Host: Raspberry Pi 4B (aarch64, SD card)
  • Bind mount at /opt/data with ~38,000 files
  • docker-compose.yml``HERMES_UID=1000 set to match Raspberry Pi's host UID 1000

Steps to Reproduce

  1. Start the Hermes container with PUID set to a non-10000 value:
docker run -d \
     --name hermes \
     --restart unless-stopped \
     -v ~/.hermes:/opt/data \
     -e PUID=1000 \
     -e PGID=1000 \
     nousresearch/hermes-agent gateway run
  1. Let it boot fully (first boot does need to chown; it will take longer on slow storage).
  2. Restart the container
  3. Observe the boot log:
hermes  | s6-rc: info: service s6rc-oneshot-runner: starting
hermes  | s6-rc: info: service s6rc-oneshot-runner successfully started
hermes  | s6-rc: info: service fix-attrs: starting
hermes  | s6-rc: info: service fix-attrs successfully started
hermes  | s6-rc: info: service legacy-cont-init: starting
hermes  | cont-init: info: running /etc/cont-init.d/01-hermes-setup
hermes  | [stage2] Changing hermes UID to 1000
hermes  | [stage2] Changing hermes GID to 1000
hermes  | [stage2] Fixing ownership of /opt/data (targeted) to hermes (1000)

Then, on storage devices with slow storage speeds and large data directories, the gateway may take a long time to start.

Expected Behavior

When the volume ownership already matches the remapped hermes user UID, needs_chown should be false and the chown -R block should be skipped entirely, making container start near-instant.

Actual Behavior

On storage devices with slow storage speeds and large data directories, the gateway may take a long time to start.

Affected Component

Other

Messaging Platform (if gateway-related)

No response

Debug Report

Not applicable. The issue is limited to Docker deployments.

Operating System

Raspberry Pi OS - Debian version 13 (trixie)

Python Version

No response

Hermes Version

Hermes Agent v0.15.1 (2026.5.29)

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

In docker/stage2-hook.sh, the needs_chown condition at lines 121-127:

actual_hermes_uid=$(id -u hermes)      # read AFTER usermod
needs_chown=false
if [ -n "${HERMES_UID:-}" ] && [ "$HERMES_UID" != "10000" ]; then
    needs_chown=true                    # ← always true when PUID is set (startup = ∞)
elif [ "$(stat -c %u "$HERMES_HOME" 2>/dev/null)" != "$actual_hermes_uid" ]; then
    needs_chown=true
fi

The usermod block (lines 45-48) has already changed id -u hermes to $HERMES_UID by this point, so actual_hermes_uid reflects the remapped UID. But the first branch checks $HERMES_UID != "10000" against a hardcoded constant rather than checking whether the filesystem already has the correct ownership. It always sets needs_chown=true whenever HERMES_UID is set to any non-default value, even if the previous boot already chowned everything.

When needs_chown=true, the script recursively chowns 12+ subdirectories (cron, sessions, logs, hooks, memories, skills, skins, plans, workspace, home, profiles) plus install trees (.venv, ui-tui, node_modules). Each chown -R must stat every file even when ownership already matches — on SD card storage this is prohibitively expensive.

Proposed Fix (optional)

Replace the two-condition check with a single ownership comparison:

if [ "$(stat -c %u "$HERMES_HOME" 2>/dev/null)" != "$actual_hermes_uid" ]; then
    needs_chown=true
fi

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Bug]: `docker/stage2-hook.sh`: `needs_chown` triggers chown on every boot when `HERMES_UID`/`PUID` is set to a non-10000 value, even if volume ownership already matches [1 pull requests]