Skip to content

fix(docker): accept PUID/PGID as aliases for HERMES_UID/HERMES_GID (#25872)#34401

Merged
benbarclay merged 1 commit into
mainfrom
salvage-25872-puid-pgid
May 29, 2026
Merged

fix(docker): accept PUID/PGID as aliases for HERMES_UID/HERMES_GID (#25872)#34401
benbarclay merged 1 commit into
mainfrom
salvage-25872-puid-pgid

Conversation

@benbarclay

Copy link
Copy Markdown
Collaborator

Salvages #25872 by @konsisumer.

Problem

NAS users (UGOS, Synology, unRAID) expect the LinuxServer.io PUID/PGID convention and bind-mount /opt/data from a host directory owned by their own UID. Without this alias, docker run -e PUID=1000 -e PGID=10 -v /volume1/docker/hermes:/opt/data ... silently leaves the runtime as UID 10000, and s6-setuidgid then drops into a hermes account that can't read the volume.

Fix

Add two alias-resolution lines to docker/stage2-hook.sh just before the existing UID/GID remap block:

HERMES_UID="${HERMES_UID:-${PUID:-}}"
HERMES_GID="${HERMES_GID:-${PGID:-}}"

HERMES_UID/HERMES_GID still take precedence when both are set (the contract test pins this).

Why this is a salvage, not a direct merge

The original PR targeted docker/entrypoint.sh. On current main that file is a 27-line deprecation shim that just execs to docker/stage2-hook.sh — the May 2026 s6-overlay rework moved all bootstrap logic to stage2-hook.sh, which is installed as /etc/cont-init.d/01-hermes-setup by the Dockerfile. The literal cherry-pick would have landed dead code.

Reconstructed the same 2-line alias resolution at the equivalent location in docker/stage2-hook.sh. The test was retargeted at the new location; the docs hunk was adapted to current main's wording ("stage2 hook" + s6-setuidgid, not the obsolete "entrypoint drops via gosu") with the NAS bind-mount example preserved verbatim.

Tests

tests/tools/test_stage2_hook_puid_pgid.py — 4 tests:

  • test_stage2_hook_resolves_puid_pgid_aliases — static check that the alias lines exist in stage2-hook.sh
  • test_puid_pgid_populate_hermes_uid_gidPUID=1000 PGID=10 → resolves to 1000:10
  • test_hermes_uid_gid_take_precedence_over_aliasesHERMES_UID=2000 PUID=1000 → resolves to 2000
  • test_no_uid_vars_leaves_values_empty — no env vars → resolves to : (default hermes user)

Test-first regression verification

Per stale-pr-triage skill: reverted just docker/stage2-hook.sh to origin/main (without the salvage's alias lines) and re-ran the new tests. Result:

FAILED test_stage2_hook_resolves_puid_pgid_aliases
FAILED test_puid_pgid_populate_hermes_uid_gid
    AssertionError: assert ':' == '1000:10'

That's the exact bug shape — PUID=1000 PGID=10 silently ignored, HERMES_UID/HERMES_GID stay empty. With the salvage applied, all 4 tests pass.

Closes #25872

Co-authored-by: konsisumer 11262660+konsisumer@users.noreply.github.com

…25872)

Salvages #25872 by @konsisumer against current main.

NAS users (UGOS, Synology, unRAID) expect the LinuxServer.io
PUID/PGID convention and bind-mount /opt/data from a host directory
owned by their own UID.  Without this alias those vars are silently
ignored and the s6-setuidgid drop to UID 10000 leaves the runtime
unable to read the volume.  HERMES_UID/HERMES_GID still take
precedence when both are set.

The original PR targeted docker/entrypoint.sh, which is now a 27-line
deprecation shim under s6-overlay (the May 2026 rework moved all
bootstrap logic to docker/stage2-hook.sh, installed as
/etc/cont-init.d/01-hermes-setup).  Re-applied the same 2-line
alias resolution at the equivalent spot in stage2-hook.sh just
before the existing UID/GID remap block.  Test was retargeted at
docker/stage2-hook.sh; docs hunk adapted to current main's wording
("stage2 hook" + s6-setuidgid, not the obsolete "entrypoint drops
via gosu") with the NAS bind-mount example preserved verbatim.

Test-first regression verification: reverted just docker/stage2-hook.sh
to origin/main and re-ran the new tests.  Result:

  FAILED test_stage2_hook_resolves_puid_pgid_aliases
  FAILED test_puid_pgid_populate_hermes_uid_gid
      AssertionError: assert ':' == '1000:10'

That's the exact bug shape — PUID=1000 PGID=10 silently ignored,
HERMES_UID/HERMES_GID stay empty.  With the salvage applied, all 4
tests pass.

Closes #25872

Co-authored-by: konsisumer <11262660+konsisumer@users.noreply.github.com>
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists area/docker Docker image, Compose, packaging labels May 29, 2026
@benbarclay benbarclay merged commit 4808321 into main May 29, 2026
22 of 26 checks passed
@benbarclay benbarclay deleted the salvage-25872-puid-pgid branch May 29, 2026 06:07
KKT-OPT pushed a commit to KKT-OPT/hermes-agent that referenced this pull request May 31, 2026
…ousResearch#25872) (NousResearch#34401)

Salvages NousResearch#25872 by @konsisumer against current main.

NAS users (UGOS, Synology, unRAID) expect the LinuxServer.io
PUID/PGID convention and bind-mount /opt/data from a host directory
owned by their own UID.  Without this alias those vars are silently
ignored and the s6-setuidgid drop to UID 10000 leaves the runtime
unable to read the volume.  HERMES_UID/HERMES_GID still take
precedence when both are set.

The original PR targeted docker/entrypoint.sh, which is now a 27-line
deprecation shim under s6-overlay (the May 2026 rework moved all
bootstrap logic to docker/stage2-hook.sh, installed as
/etc/cont-init.d/01-hermes-setup).  Re-applied the same 2-line
alias resolution at the equivalent spot in stage2-hook.sh just
before the existing UID/GID remap block.  Test was retargeted at
docker/stage2-hook.sh; docs hunk adapted to current main's wording
("stage2 hook" + s6-setuidgid, not the obsolete "entrypoint drops
via gosu") with the NAS bind-mount example preserved verbatim.

Test-first regression verification: reverted just docker/stage2-hook.sh
to origin/main and re-ran the new tests.  Result:

  FAILED test_stage2_hook_resolves_puid_pgid_aliases
  FAILED test_puid_pgid_populate_hermes_uid_gid
      AssertionError: assert ':' == '1000:10'

That's the exact bug shape — PUID=1000 PGID=10 silently ignored,
HERMES_UID/HERMES_GID stay empty.  With the salvage applied, all 4
tests pass.

Closes NousResearch#25872

Co-authored-by: konsisumer <11262660+konsisumer@users.noreply.github.com>
hechuyi pushed a commit to hechuyi/hermes-agent that referenced this pull request Jun 6, 2026
…ousResearch#25872) (NousResearch#34401)

Salvages NousResearch#25872 by @konsisumer against current main.

NAS users (UGOS, Synology, unRAID) expect the LinuxServer.io
PUID/PGID convention and bind-mount /opt/data from a host directory
owned by their own UID.  Without this alias those vars are silently
ignored and the s6-setuidgid drop to UID 10000 leaves the runtime
unable to read the volume.  HERMES_UID/HERMES_GID still take
precedence when both are set.

The original PR targeted docker/entrypoint.sh, which is now a 27-line
deprecation shim under s6-overlay (the May 2026 rework moved all
bootstrap logic to docker/stage2-hook.sh, installed as
/etc/cont-init.d/01-hermes-setup).  Re-applied the same 2-line
alias resolution at the equivalent spot in stage2-hook.sh just
before the existing UID/GID remap block.  Test was retargeted at
docker/stage2-hook.sh; docs hunk adapted to current main's wording
("stage2 hook" + s6-setuidgid, not the obsolete "entrypoint drops
via gosu") with the NAS bind-mount example preserved verbatim.

Test-first regression verification: reverted just docker/stage2-hook.sh
to origin/main and re-ran the new tests.  Result:

  FAILED test_stage2_hook_resolves_puid_pgid_aliases
  FAILED test_puid_pgid_populate_hermes_uid_gid
      AssertionError: assert ':' == '1000:10'

That's the exact bug shape — PUID=1000 PGID=10 silently ignored,
HERMES_UID/HERMES_GID stay empty.  With the salvage applied, all 4
tests pass.

Closes NousResearch#25872

Co-authored-by: konsisumer <11262660+konsisumer@users.noreply.github.com>
(cherry picked from commit 4808321)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docker Docker image, Compose, packaging P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants