fix(docker/tui): chown ui-tui to hermes + actionable build error (#20500)#20509
Open
Beandon13 wants to merge 1 commit into
Open
fix(docker/tui): chown ui-tui to hermes + actionable build error (#20500)#20509Beandon13 wants to merge 1 commit into
Beandon13 wants to merge 1 commit into
Conversation
…sResearch#20500) Three coordinated changes for the dashboard "Chat unavailable: 1" banner reported in NousResearch#20500: 1. Dockerfile: chown ``/opt/hermes/ui-tui`` to ``hermes:hermes`` after the build step. ``COPY --chown=hermes:hermes . .`` runs before the build, but ``RUN cd ui-tui && npm run build`` executes as root and leaves ``ui-tui/dist/`` and ``ui-tui/packages/hermes-ink/dist/`` root-owned. When ``_tui_build_needed`` later trips and esbuild tries to rewrite those dist files as the ``hermes`` user, it fails with EACCES. 2. ``docker/entrypoint.sh``: defensive recursive chown of ``$INSTALL_DIR/ui-tui`` while still running as root, before the gosu drop. Handles the case where ``HERMES_UID`` remaps the runtime hermes UID — the Dockerfile's build-time chown was for the image-default UID 10000, so the tree appears foreign-owned to the remapped runtime user. Silent failure on rootless containers where chown isn't permitted. 3. ``hermes_cli/main.py``: replace ``sys.exit(1)`` in ``_make_tui_argv`` with ``raise SystemExit("<reason>")`` so ``pty_ws`` (which renders ``Chat unavailable: {exc}``) shows an actionable message instead of a bare ``Chat unavailable: 1``. EACCES in the build output is detected and surfaced explicitly with the chown remedy. Adds tests/hermes_cli/test_tui_build_failure_message.py covering both the EACCES-detection path and the generic build-failure path.
Closed
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #20500 — the dashboard's embedded Chat tab fails on first connect in the official Docker image with the unhelpful banner "Chat unavailable: 1".
Root cause (per the issue's reproduction)
Three compounding factors:
COPY --chown=hermes:hermes . .chowns the source tree, but theRUN cd ui-tui && npm run buildstep executes as root (no precedingUSERdirective). The artifacts written intoui-tui/dist/andui-tui/packages/hermes-ink/dist/end up root-owned.gosu hermes. When_make_tui_argvdecides the bundle is stale and rerunsnpm run build, esbuild fails with EACCES on the root-owned dist dirs._make_tui_argvcallssys.exit(1).web_server.pty_wscatches the resultingSystemExitand rendersChat unavailable: {exc}—str(SystemExit(1))is just\"1\", hence the unhelpful banner.Fix
Three coordinated changes (each independent, but together close the bug for both new images and remapped-UID deployments):
Dockerfile— chown/opt/hermes/ui-tuitohermes:hermesimmediately afternpm run build. Survives image rebuilds, so users no longer have to chown manually after everydocker compose pull. (Implements suggestion 1 in the issue.)docker/entrypoint.sh— defensive recursive chown of$INSTALL_DIR/ui-tuiwhile still running as root, before the gosu drop. Handles theHERMES_UIDremap case where the Dockerfile's build-time chown is for UID 10000 but the runtime user has a different UID. Silent failure on rootless containers where chown isn't permitted. (Implements suggestion 2.)hermes_cli/main.py— replace baresys.exit(1)in_make_tui_argvwithraise SystemExit(\"<reason>\")sopty_wsshows an actionable message. EACCES in the build output is detected and surfaced explicitly with the chown remedy and a pointer to issue Dashboard Chat tab fails with EACCES in Docker image — /opt/hermes/ui-tui is root-owned but dashboard runs as hermes #20500. (Implements the bonus surfacing improvement.)Test plan
tests/hermes_cli/test_tui_build_failure_message.py:SystemExitwith message containing "permission denied" + "Dashboard Chat tab fails with EACCES in Docker image — /opt/hermes/ui-tui is root-owned but dashboard runs as hermes #20500"SystemExitwith descriptive message (not bare1)tests/hermes_cli/test_tui_npm_install.pyandtest_tui_resume_flow.pystill passHERMES_DASHBOARD=1, open Chat tab — banner should not appearCompatibility
ui-tui/.SystemExit(\"<str>\")returns a non-zero exit code (the str), so launchers that key onreturncode != 0still see a non-zero exit.