mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-04 07:31:58 +00:00
The s6-overlay migration replaced every runtime use of gosu with s6-setuidgid (in stage2-hook.sh, main-wrapper.sh, per-service run scripts, and cont-init.d hooks), but the gosu binary itself was still being copied into the image from tianon/gosu, and several comments across the repo still pointed to it. Image changes: - Drop the FROM tianon/gosu:1.19-trixie AS gosu_source stage - Drop the COPY --from=gosu_source /gosu /usr/local/bin/ layer - Net: one fewer base-image pull, ~12-15 MB layer eliminated Documentation/comment refresh (no behavior change): - Dockerfile: update root-user rationale comment + cont-init.d comment - docker/main-wrapper.sh: drop "pre-s6 contract (gosu drop)" reference - docker-compose.yml: update UID/GID remap comment - .hadolint.yaml: update DL3002 ignore rationale - website/docs/user-guide/docker.md: privilege-drop helper is s6-setuidgid now - hermes_cli/config.py: docker_run_as_host_user docstring tools/environments/docker.py runs *arbitrary user images* via the terminal backend, not the bundled Hermes image. It still needs SETUID/ SETGID caps so user images that use gosu/su/s6-setuidgid all work. Renamed the cap-list constant _GOSU_CAP_ARGS → _PRIVDROP_CAP_ARGS and updated comments to list s6-setuidgid alongside the others as examples. The matching test (test_security_args_include_setuid_setgid_for_gosu_drop → test_security_args_include_setuid_setgid_for_privdrop) was renamed and its docstring updated; behavior is unchanged. Verification: - hadolint clean against .hadolint.yaml - shellcheck clean against all docker/ shell scripts - Image rebuilt successfully (sha 1a090924ccea) - Docker harness: 19 passed in 41.87s (every Phase 0 test + Phase 4 per-profile-gateway lifecycle + container-restart reconciliation) - tests/tools/test_docker_environment.py: 23 passed (rename did not break test discovery; pre-existing unrelated mock warning) The plan document (docs/plans/2026-05-07-s6-overlay-dynamic-subagent-gateways.md) intentionally retains its historical references to gosu — it describes the pre-s6 entrypoint as background for understanding the migration.
36 lines
1.6 KiB
YAML
36 lines
1.6 KiB
YAML
# hadolint configuration for the Hermes Agent Dockerfile.
|
|
# See https://github.com/hadolint/hadolint#configure for rules.
|
|
#
|
|
# We want hadolint to surface NEW Dockerfile lint regressions, but we
|
|
# don't want to rewrite the existing image to silence rules that are
|
|
# either intentional or pragmatic tradeoffs for this project. Each
|
|
# ignore below has a one-line justification.
|
|
failure-threshold: warning
|
|
|
|
ignored:
|
|
# Pin versions in apt get install. We intentionally don't pin common
|
|
# tools (curl, git, openssh-client, etc.) — security updates flow in
|
|
# via the periodic base-image rebuild, and pinning would lock us to
|
|
# superseded patch releases. Same rationale as nearly every distro-
|
|
# base official image (python, node, debian).
|
|
- DL3008
|
|
# Use WORKDIR to switch to a directory. The image uses `(cd web && …)`
|
|
# / `(cd ../ui-tui && …)` inline subshells for one-off build steps
|
|
# because they don't affect later RUN commands; promoting them to
|
|
# full WORKDIR switches with restores would obscure intent.
|
|
- DL3003
|
|
# Multiple consecutive RUN instructions. The `touch README.md` + `uv
|
|
# sync` split is intentional — `touch` is cheap, `uv sync` is the
|
|
# expensive layer-cached step we want isolated, and merging them
|
|
# would invalidate the cache for trivial changes.
|
|
- DL3059
|
|
# Last USER should not be root. /init (s6-overlay) runs as root so the
|
|
# stage2 hook can usermod/groupmod and chown the data volume per
|
|
# HERMES_UID at runtime; each supervised service then drops to the
|
|
# hermes user via `s6-setuidgid`.
|
|
- DL3002
|
|
|
|
# Require explicit base-image pins (SHA256) — we already do this.
|
|
trustedRegistries:
|
|
- docker.io
|
|
- ghcr.io
|