From 8254b820ec8cbc930aef25897df24e266d8bf1a2 Mon Sep 17 00:00:00 2001 From: angelos Date: Fri, 10 Apr 2026 03:17:40 +0000 Subject: [PATCH] fix(docker): --init for zombie reaping + sleep infinity for idle-based lifetime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two issues with sandbox container spawning: 1. PID 1 was `sleep 2h` which doesn't call wait() — every background process that exited became a zombie (), and the process tool reported them as "running" because zombie PIDs still exist in the process table. Fix: add --init to docker run, which uses tini (Docker) or catatonit (Podman) as PID 1 to reap children automatically. Both runtimes support --init natively. 2. The fixed 2-hour lifetime was arbitrary and sometimes too short for long agent sessions. Fix: replace 'sleep 2h' with 'sleep infinity'. The idle reaper (_cleanup_inactive_envs, gated by terminal.lifetime_seconds, default 300s) already handles cleanup based on last activity timestamp — there's no need for the container itself to have a fixed death timer. Fixes #6908. --- tools/environments/docker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/environments/docker.py b/tools/environments/docker.py index a6e87180..2341778f 100644 --- a/tools/environments/docker.py +++ b/tools/environments/docker.py @@ -409,11 +409,12 @@ class DockerEnvironment(BaseEnvironment): container_name = f"hermes-{uuid.uuid4().hex[:8]}" run_cmd = [ self._docker_exe, "run", "-d", + "--init", # tini/catatonit as PID 1 — reaps zombie children "--name", container_name, "-w", cwd, *all_run_args, image, - "sleep", "2h", + "sleep", "infinity", # no fixed lifetime — idle reaper handles cleanup ] logger.debug(f"Starting container: {' '.join(run_cmd)}") result = subprocess.run(