fix(docker): support s6 /init images in terminal sandbox (#34628)#34635
Merged
benbarclay merged 1 commit intoJun 1, 2026
Merged
Conversation
…h#34628) s6-overlay images (e.g. hermes-agent:latest) use /init as PID 1 and exec /run/s6/basedir/bin/init during stage0 startup. The Docker terminal backend unconditionally added Docker --init and mounted /run as noexec, which broke those images in two ways: --init created a second competing PID-1 init, and the noexec /run made s6 stage0 fail with "exec: /run/s6/basedir/bin/init: Permission denied" (exit 126), so the container died and terminal commands reported a generic "container is not running" error. Detect images whose entrypoint is /init via 'docker image inspect' and, for those images only, skip Docker --init and mount /run with exec. All other images keep the hardened --init + noexec defaults. Detection is best-effort: any inspect failure falls back to the safe defaults.
JoeKowal
pushed a commit
to JoeKowal/hermes-agent
that referenced
this pull request
Jun 4, 2026
…h#34628) (NousResearch#34635) s6-overlay images (e.g. hermes-agent:latest) use /init as PID 1 and exec /run/s6/basedir/bin/init during stage0 startup. The Docker terminal backend unconditionally added Docker --init and mounted /run as noexec, which broke those images in two ways: --init created a second competing PID-1 init, and the noexec /run made s6 stage0 fail with "exec: /run/s6/basedir/bin/init: Permission denied" (exit 126), so the container died and terminal commands reported a generic "container is not running" error. Detect images whose entrypoint is /init via 'docker image inspect' and, for those images only, skip Docker --init and mount /run with exec. All other images keep the hardened --init + noexec defaults. Detection is best-effort: any inspect failure falls back to the safe defaults.
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
/init(e.g.hermes-agent:latest).noexec/runthat kills s6 stage0.Motivation
Closes #34628.
The Docker backend unconditionally added Docker
--initand mounted/runas--tmpfs /run:rw,noexec,nosuid,size=64m. For images that already use s6/initas PID 1 this breaks startup in two stages:
--initconflicts with the image's own/initentrypoint (two PID-1 inits).--init, s6 stage0 execs/run/s6/basedir/bin/init, whichfails on a
noexecmount withexec: /run/s6/basedir/bin/init: Permission deniedand the container exits with code
126. The terminal tool then reports thegeneric "container ... is not running" error.
This matches the reporter's own root-cause analysis and proposed fix exactly.
Fix
_image_uses_init_entrypoint(docker_exe, image)inspectsthe image's entrypoint via
docker image inspect ... --format '{{json .Config.Entrypoint}}'and returns True when it is
/init(or the canonical s6 path)._build_security_argsgains arun_execparameter;/runis split out of theshared base args so it can be mounted
execfor s6 images andnoexecotherwise.docker runomits--initfor s6 images.--init+noexecdefaults. Any inspectfailure (image not pulled, daemon error) falls back to the safe defaults — the
image will still be pulled by the subsequent
docker run.Verification
python3 -m pytest tests/tools/test_docker_environment.py— 61 passed (7 new):_image_uses_init_entrypointdetection for/init, plain image,null,inspect-failure, and subprocess-exception (defaults kept) cases.
/initimage →docker runomits--initand mounts/runexec.--initandnoexec/run.python3 -m pytest tests/tools/test_docker_find.py tests/tools/test_dockerfile_pid1_reaping.py— 16 passed.docker image inspect; non-s6 behavior is byte-identical to before.