From 7847a58b3a9735a4214d1ee081725f8c8e8d063d Mon Sep 17 00:00:00 2001 From: vaddisrinivas <38348871+vaddisrinivas@users.noreply.github.com> Date: Fri, 15 May 2026 10:27:07 -0400 Subject: [PATCH] fix(docker): preload messaging gateway deps --- Dockerfile | 18 ++++++++++-------- tests/tools/test_dockerfile_pid1_reaping.py | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8655c51f34c..bde3412ed7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -66,9 +66,11 @@ RUN npm install --prefer-offline --no-audit && \ # frontend stats the readme path during dep resolution, so we `touch` an # empty placeholder — the real README is restored by `COPY . .` below. # -# `uv sync --frozen --no-install-project --extra all` installs only the -# deps reachable through the composite `[all]` extra (handpicked set -# intended for the production image). We do NOT use `--all-extras`: +# `uv sync --frozen --no-install-project --extra all --extra messaging` +# installs the deps reachable through the composite `[all]` extra +# (handpicked set intended for the production image), plus gateway +# messaging adapters that should work in the published image without a +# first-boot lazy install. We do NOT use `--all-extras`: # that would pull in `[rl]` (atroposlib + tinker + torch + wandb from # git), `[yc-bench]` (another git dep), and `[termux-all]` (Android # redundancy), none of which belong in the published container. @@ -76,7 +78,7 @@ RUN npm install --prefer-offline --no-audit && \ # The editable link is created after the source copy below. COPY pyproject.toml uv.lock ./ RUN touch ./README.md -RUN uv sync --frozen --no-install-project --extra all +RUN uv sync --frozen --no-install-project --extra all --extra messaging # ---------- Source code ---------- # .dockerignore excludes node_modules, so the installs above survive. @@ -94,10 +96,10 @@ 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. +# The .venv MUST remain hermes-writable so lazy_deps.py can install +# remaining optional platform packages and future pin bumps at first use. +# Without this, `uv pip install` fails with EACCES and 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/.venv /opt/hermes/ui-tui /opt/hermes/node_modules diff --git a/tests/tools/test_dockerfile_pid1_reaping.py b/tests/tools/test_dockerfile_pid1_reaping.py index e578d8a69fd..70d95807aa7 100644 --- a/tests/tools/test_dockerfile_pid1_reaping.py +++ b/tests/tools/test_dockerfile_pid1_reaping.py @@ -121,6 +121,20 @@ def test_dockerfile_installs_tui_dependencies(dockerfile_text): ) +def test_dockerfile_preinstalls_gateway_messaging_dependencies(dockerfile_text): + sync_steps = [ + step for step in _run_steps(dockerfile_text) + if "uv sync" in step and "--no-install-project" in step + ] + + assert sync_steps, "Dockerfile must install Python dependencies with uv sync" + assert any("--extra messaging" in step for step in sync_steps), ( + "Published Docker images must preload the [messaging] extra so " + "Telegram/Discord gateway adapters do not depend on first-boot " + "lazy installation (#24698)." + ) + + def test_dockerfile_builds_tui_assets(dockerfile_text): assert any( "ui-tui" in step and "npm" in step and "run build" in step