From fb298a958c525fc80d1111f298afca8ce7a063a9 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 27 May 2026 17:08:23 +1000 Subject: [PATCH] fix(docker): mkdir HERMES_HOME as root in stage2 before chown / privilege drop (#18488) When HERMES_HOME points at a custom path whose parent directories only root can create (e.g. HERMES_HOME=/home/hermes/.hermes in a Compose file, or any path under a fresh / not pre-populated by the image), stage2-hook.sh fails on first boot: [stage2] Warning: chown failed (rootless container?) - continuing mkdir: cannot create directory '/custom': Permission denied mkdir: cannot create directory '/custom': Permission denied ... (one per s6-setuidgid hermes mkdir invocation) cont-init: info: /etc/cont-init.d/01-hermes-setup exited 1 The mkdirs fail because s6-setuidgid drops to hermes (UID 10000) before invoking mkdir -p, and the runtime user has no permission to create root-owned ancestor directories. 02-reconcile-profiles then crashes with FileNotFoundError, .install_method never lands, and the container limps on in a half-initialized state. Bootstrap HERMES_HOME with mkdir -p while still root, before the ownership normalization. Idempotent on the default /opt/data path (directory already exists from the Dockerfile RUN mkdir -p) and on any subsequent restart. (#18482) Retargeted from the original PR's docker/entrypoint.sh (now a deprecated shim) to docker/stage2-hook.sh where the related chown logic moved during the s6-overlay rework. Co-authored-by: wpengpeng168 <133926080+wpengpeng168@users.noreply.github.com> --- docker/stage2-hook.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docker/stage2-hook.sh b/docker/stage2-hook.sh index 131c76f77da..1c41c6967ac 100755 --- a/docker/stage2-hook.sh +++ b/docker/stage2-hook.sh @@ -20,6 +20,18 @@ set -eu HERMES_HOME="${HERMES_HOME:-/opt/data}" INSTALL_DIR="/opt/hermes" +# --- Bootstrap HERMES_HOME as root --- +# Create the directory (and any missing parents) while we still have root +# privileges so the chown checks below see real metadata and the later +# `s6-setuidgid hermes mkdir -p` block doesn't EACCES on root-owned +# ancestors. Without this, custom HERMES_HOME paths whose parents only +# root can create (e.g. `HERMES_HOME=/home/hermes/.hermes` in a Compose +# file, or any path under a fresh / not pre-populated by the image) +# fail on first boot with `mkdir: cannot create directory '/...': Permission +# denied` and the cont-init hook exits non-zero. Idempotent — `mkdir -p` +# is a no-op if the dir already exists. (#18482, salvages #18488) +mkdir -p "$HERMES_HOME" + # --- UID/GID remap --- if [ -n "${HERMES_UID:-}" ] && [ "$HERMES_UID" != "$(id -u hermes)" ]; then echo "[stage2] Changing hermes UID to $HERMES_UID"