Background process termination crashes Claude Code in Docker containers
When running Claude Code inside a Docker container, killing background processes (either manually with k or when Claude autonomously decides to kill them) causes Claude Code itself to crash with exit code 137 (SIGKILL).
Environment
- Claude Code v2.0.76
- Running inside Docker container (python:3.12-slim base)
- Container started via
docker exec -it <container> /bin/bash
Steps to Reproduce
- Run Claude Code inside a Docker container
- Start a background process using Claude's built-in background feature:
````
> start the backend server
● Bash(uvicorn api:app --port 8000) timeout: 10m
⎿ Running in the background (↓ to manage)
- Press
↓to view background tasks, thenkto kill the process - Claude Code exits/crashes immediately
Expected Behavior
Claude Code should kill only the background process and continue running.
Actual Behavior
Claude Code crashes with exit code 137 (SIGKILL). The signal sent to kill the background process also kills Claude itself.
Root Cause Analysis
The issue appears to be that Claude Code and its spawned background processes share the same process group. When Claude sends a signal to kill the process group (e.g., kill -PGID), it kills itself too.
Workaround
Manually using setsid to isolate background processes works:
setsid uvicorn api:app --port 8000 > /tmp/server.log 2>&1 &
However, this loses Claude's background process monitoring and notification features.
Suggested Fix
Claude Code should spawn background processes in isolated process groups using setsid or setpgid() internally, while maintaining its monitoring wrapper. This would prevent signal propagation while preserving the background task management UI.
Additional Context
- Tried
docker run --init- doesn't help since Claude runs viadocker exec - Tried
script -q -c "claude ..." /dev/null- still crashes - Tried
setsid claude ...- Claude loses terminal input - Only
setsidon the child processes works, but loses monitoring
16 Comments
This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.
This issue is still occurring
This is still occurring.
This is still occurring
Still occurring, happens when running claude using
docker sandbox+1 on the diagnosis — shared process group between parent (Claude Code) and spawned background tasks is the root cause, and
setsid/setpgidon the children is the right shape of fix.One nuance worth calling out for anyone landing here: once you isolate children into their own pgid, the kill path also has to change.
kill -<PID>(negative PID, kill-by-pgid) on the child's new group is what you want; a plainkill <PID>will only hit the immediate child and leave MCP grandchildren / npx wrappers behind as orphans (which is the other failure mode tracked in #22612 and #33947).In Rust, that maps to:
Command::process_group(0)(orpre_exec(|| { libc::setsid(); Ok(()) })on older toolchains)libc::killpg(pgid, SIGKILL)— neverkill(child_pid, ...)That combination keeps the parent alive, contains the blast radius to the child tree, and avoids the orphan-MCP accumulation that shows up under PPID=1 on macOS / docker-init on Linux. The
setsid uvicorn …workaround you found works for the same reason — it's just doing the pgid isolation by hand at the shell level, at the cost of losing the monitoring UI hooks.still has this issue
The issue is still triggering constantly.
This issue is still occurring
+1 daily
+1 happening frequently without any clear reason
been living with it for months! happy to see someone found the root cause - now please lets fix it
still happens
Still bugging me
still has this issue
for me too.. :(