From 9ef1ae138ab349004c9cceec19b32b7bce59d544 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sun, 26 Apr 2026 08:27:39 -0700 Subject: [PATCH] fix(docker): don't chown config.yaml after gosu drop (#15865) (#16096) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The chown/chmod block on config.yaml was added in b24d239ce to keep the file readable by the hermes runtime user, but it sat in the post-gosu 'running as hermes' section of the entrypoint. That meant: 1. Default `docker run ` — container starts as root, entrypoint drops to hermes via gosu, then non-root hermes tries to chown the file to hermes. Works by coincidence because the file was just created by root during volume setup and gosu target == target owner. 2. `docker run -u $(id -u):$(id -g) ` (#15865) — container starts as the caller's UID. The root block is skipped entirely, we land in the hermes section as some arbitrary non-root user, and chown to 'hermes' fails with 'Operation not permitted'. Script aborts under `set -e`. Move the chown/chmod into the root block (before the gosu exec) where it actually has privilege, and guard with `2>/dev/null || true` so rootless Podman (where even in-container root lacks host-side chown rights) doesn't abort either. Closes #15865 --- docker/entrypoint.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 0be1d656..299aab97 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -41,6 +41,15 @@ if [ "$(id -u)" = "0" ]; then echo "Warning: chown failed (rootless container?) — continuing anyway" fi + # Ensure config.yaml is readable by the hermes runtime user even if it was + # edited on the host after initial ownership setup. Must run here (as root) + # rather than after the gosu drop, otherwise a non-root caller like + # `docker run -u $(id -u):$(id -g)` hits "Operation not permitted" (#15865). + if [ -f "$HERMES_HOME/config.yaml" ]; then + chown hermes:hermes "$HERMES_HOME/config.yaml" 2>/dev/null || true + chmod 640 "$HERMES_HOME/config.yaml" 2>/dev/null || true + fi + echo "Dropping root privileges" exec gosu hermes "$0" "$@" fi @@ -67,13 +76,6 @@ if [ ! -f "$HERMES_HOME/config.yaml" ]; then cp "$INSTALL_DIR/cli-config.yaml.example" "$HERMES_HOME/config.yaml" fi -# Ensure the main config file remains accessible to the hermes runtime user -# even if it was edited on the host after initial ownership setup. -if [ -f "$HERMES_HOME/config.yaml" ]; then - chown hermes:hermes "$HERMES_HOME/config.yaml" - chmod 640 "$HERMES_HOME/config.yaml" -fi - # SOUL.md if [ ! -f "$HERMES_HOME/SOUL.md" ]; then cp "$INSTALL_DIR/docker/SOUL.md" "$HERMES_HOME/SOUL.md"