From 942adf617910f50a39f41bd200d8083bf4cb2bed Mon Sep 17 00:00:00 2001 From: Siddharth Balyan <52913345+alt-glitch@users.noreply.github.com> Date: Wed, 13 May 2026 11:55:07 +0530 Subject: [PATCH] fix(docker): chown .venv to hermes so lazy_deps can install platform packages (#24841) The Dockerfile permissions section made /opt/hermes/.venv readable but not writable by the hermes runtime user. Since the 2026-05-12 policy change moved messaging packages (discord.py, telegram, slack, etc.) out of [all] and into lazy_deps.py, the Docker image no longer ships with them pre-installed. At first gateway boot, lazy_deps.ensure() tries to `uv pip install` them into the venv but fails with EACCES because site-packages is root-owned. The result: every messaging platform adapter silently fails to load inside Docker containers, producing only a cryptic "discord.py not installed" warning despite the gateway being correctly configured. Two-part fix: 1. Dockerfile: add /opt/hermes/.venv to the existing chown -R hermes:hermes line so the default (UID 10000) case works out of the box. 2. docker/entrypoint.sh: extend the needs_chown block to also re-chown the .venv when HERMES_UID is remapped. Without this, the build-time chown becomes stale when someone uses the documented HERMES_UID override in docker-compose.yml. Fixes #21536 Related: #17674, #21543, #21755 --- Dockerfile | 6 +++++- docker/entrypoint.sh | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ee2c491c069..8655c51f34c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -94,9 +94,13 @@ RUN cd web && npm run build && \ # hermes_cli/main.py succeeds (see #18800). /opt/hermes/web is build-time # only (HERMES_WEB_DIST points at hermes_cli/web_dist) and is intentionally # not chowned here. +# The .venv MUST be hermes-writable so lazy_deps.py can install platform +# packages (discord.py, telegram, slack, etc.) at first gateway boot. +# Without this, `uv pip install` fails with EACCES and all messaging +# adapters silently fail to load. See tools/lazy_deps.py. USER root RUN chmod -R a+rX /opt/hermes && \ - chown -R hermes:hermes /opt/hermes/ui-tui /opt/hermes/node_modules + chown -R hermes:hermes /opt/hermes/.venv /opt/hermes/ui-tui /opt/hermes/node_modules # Start as root so the entrypoint can usermod/groupmod + gosu. # If HERMES_UID is unset, the entrypoint drops to the default hermes user (10000). diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 288ae2614bb..09e870543a2 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -39,6 +39,10 @@ if [ "$(id -u)" = "0" ]; then # by the mapped user on the host side. chown -R hermes:hermes "$HERMES_HOME" 2>/dev/null || \ echo "Warning: chown failed (rootless container?) — continuing anyway" + # The .venv must also be re-chowned when UID is remapped, otherwise + # lazy_deps.py cannot install platform packages (discord.py, etc.). + chown -R hermes:hermes "$INSTALL_DIR/.venv" 2>/dev/null || \ + echo "Warning: chown .venv failed (rootless container?) — continuing anyway" fi # Ensure config.yaml is readable by the hermes runtime user even if it was