Skip to content

fix(docker): support s6 /init images in terminal sandbox (#34628)#34635

Merged
benbarclay merged 1 commit into
NousResearch:mainfrom
Bartok9:fix-34628-s6-init-docker-sandbox
Jun 1, 2026
Merged

fix(docker): support s6 /init images in terminal sandbox (#34628)#34635
benbarclay merged 1 commit into
NousResearch:mainfrom
Bartok9:fix-34628-s6-init-docker-sandbox

Conversation

@Bartok9

@Bartok9 Bartok9 commented May 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Docker terminal sandboxes now start correctly for s6-overlay images whose entrypoint is /init (e.g. hermes-agent:latest).
  • Such images no longer get a second competing PID-1 init or a noexec /run that kills s6 stage0.

Motivation

Closes #34628.

The Docker backend unconditionally added Docker --init and mounted /run as
--tmpfs /run:rw,noexec,nosuid,size=64m. For images that already use s6 /init
as PID 1 this breaks startup in two stages:

  1. Docker --init conflicts with the image's own /init entrypoint (two PID-1 inits).
  2. Even after skipping --init, s6 stage0 execs /run/s6/basedir/bin/init, which
    fails on a noexec mount with exec: /run/s6/basedir/bin/init: Permission denied
    and the container exits with code 126. The terminal tool then reports the
    generic "container ... is not running" error.

This matches the reporter's own root-cause analysis and proposed fix exactly.

Fix

  • New best-effort helper _image_uses_init_entrypoint(docker_exe, image) inspects
    the 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_args gains a run_exec parameter; /run is split out of the
    shared base args so it can be mounted exec for s6 images and noexec otherwise.
  • docker run omits --init for s6 images.
  • All non-s6 images keep the hardened --init + noexec defaults. Any inspect
    failure (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_entrypoint detection for /init, plain image, null,
      inspect-failure, and subprocess-exception (defaults kept) cases.
    • s6 /init image → docker run omits --init and mounts /run exec.
    • non-s6 image → keeps --init and noexec /run.
  • python3 -m pytest tests/tools/test_docker_find.py tests/tools/test_dockerfile_pid1_reaping.py — 16 passed.
  • Detection is gated behind a single docker image inspect; non-s6 behavior is byte-identical to before.

…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.
@alt-glitch alt-glitch added type/bug Something isn't working backend/docker Docker container execution area/docker Docker image, Compose, packaging P2 Medium — degraded but workaround exists labels May 29, 2026
@benbarclay benbarclay merged commit 064875a into NousResearch:main Jun 1, 2026
20 checks passed
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docker Docker image, Compose, packaging backend/docker Docker container execution P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Docker terminal sandboxes fail to start for s6 /init images

3 participants