Verified SOP & TutorialAudited Score 98/100

The Complete Production SOP: How to Deploy and Run Tini Lightweight Init System & Zombie Process Reaping in Autonomous AI Agents

Deploy Tini lightweight init system to reap zombies & handle POSIX signals in Docker containers via Codex, Claude Code, Cursor, and Windsurf SOPs.

Target Runtimes:codexclaude-codecursorwindsurf
5 min read • Updated for 2026

Technical Overview & Architectural Context

Autonomous coding agents frequently generate Dockerfiles using standard exec or shell forms (e.g., CMD ["node", "server.js"]) without an init system. In Linux containers, the primary process runs as PID 1. Standard application runtimes like Node.js, Python, or Go are not built to function as an init system: they fail to reap orphaned child processes generated by subshells, causing process table exhaustion ('zombie' defunct processes). Furthermore, typical application processes ignore default SIGTERM signals when mapped to PID 1, preventing graceful shutdowns and forcing the Docker daemon to brutally send SIGKILL after a 10-second timeout. When AI agents generate or refactor container entrypoints, they repeatedly hallucinate incorrect entrypoint formats, chain commands using shell wrappers (e.g., ENTRYPOINT /entrypoint.sh) which creates an intermediate shell process as PID 1, or omit signal forwarding flags. Without procedural constraints, agents fail to inspect container process trees or distinguish between host-level init flags (`--init`) and container-level binary packaging. This skill enforces deterministic SOP boundaries for the 'tini-docker-init-zombie-reaper' workflow. It forces autonomous agents across Codex, Claude Code, Cursor, and Windsurf to install Tini, configure the exec-form array ENTRYPOINT properly, verify signal delegation, and validate process trees using deterministic verification checklists.

Prerequisites & Environment Requirements

Codex Desktop, Claude Code CLI (v0.2.9+), Cursor (v0.40+), or Windsurf IDE installed
Docker Engine 24.0+ or Docker Desktop with buildx support
Git 2.40+ with initialized workspace repository
Local shell access (Bash/Zsh) with standard POSIX toolchain

Verified Search Intents & Long-Tail Queries Solved

SEO Audit Score: 98/100

This operational tutorial is engineered to provide deterministic solutions for these developer search queries:

#install tini-docker-init-zombie-reaper in cursor ide#claude code tini docker init rules#codex desktop tini zombie process reaping tutorial#how to fix docker zombie process tini entrypoint error#deterministic devops agent SOP docker init#tini-docker-init-zombie-reaper sandbox permissions and security score#docker pid 1 tini graceful shutdown prompt examples and triggers#windsurf ide tini entrypoint exec syntax setup

Step-by-Step Execution Playbook

1

Local Environment Setup & SKILL.md Mounting

Create the local skill manifest directory and inject verified procedural rules into the agent context.

Agent runtimes like Claude Code and Cursor scan predefined project directories (`.claude/skills`, `.cursor/rules`, or global `~/.agents/skills`) for procedural markdown files. Placing the SKILL.md in the workspace exposes explicit entrypoint rules, execution commands, and verification gates directly into the agent's active execution loop.

Terminal Command
mkdir -p .agents/skills/tini-docker-init-zombie-reaper && cat << 'EOF' > .agents/skills/tini-docker-init-zombie-reaper/SKILL.md --- name: "tini-docker-init-zombie-reaper" description: "Reap zombie child processes and handle POSIX signals correctly inside Docker containers." metadata: author: "Thomas Orozco" version: "1.0.0" runtime_compatibility: - "codex" - "claude-code" - "cursor" - "windsurf" triggers: - "setup tini docker init" - "reap zombie processes container" - "graceful shutdown docker tini" permissions: fs_read: true fs_write: "workspace" shell_exec: false net_access: false --- # Tini Lightweight Init System & Zombie Process Reaping Configures Tini inside container images: running as PID 1, properly forwarding signals (SIGTERM, SIGINT) to child processes, reaping orphaned zombie processes, and preventing resource leaks in long-running containers. ## Execution SOP & Rules 1. Install tini via package manager: RUN apk add --no-cache tini (or apt-get install -y --no-install-recommends tini). 2. Define entrypoint using exec array syntax: ENTRYPOINT ["/sbin/tini", "--", "/app/entrypoint.sh"]. 3. Never use shell string syntax for ENTRYPOINT when invoking tini. 4. Verify PID 1 is occupied by tini by inspecting 'ps aux' inside the running container. EOF
.agents/skills/tini-docker-init-zombie-reaper/SKILL.md
---
name: "tini-docker-init-zombie-reaper"
description: "Reap zombie child processes and handle POSIX signals correctly inside Docker containers."
metadata:
  author: "Thomas Orozco"
  version: "1.0.0"
  runtime_compatibility:
    - "codex"
    - "claude-code"
    - "cursor"
    - "windsurf"
triggers:
  - "setup tini docker init"
  - "reap zombie processes container"
  - "graceful shutdown docker tini"
permissions:
  fs_read: true
  fs_write: "workspace"
  shell_exec: false
  net_access: false
---
Production Pro-Tip

Use local project-level mounting (.agents/skills) to allow git tracking across team members while saving global system context tokens.

Sandbox Gotcha

Ensure file permissions allow agent read access. If running inside restricted workspace sandboxes, verify the agent daemon has read permissions on .agents/.

2

Environment & Package Manager Dependency Alignment

Instruct the agent to inspect the base container image OS family and map the appropriate Tini package or static binary.

Different Linux distributions package Tini in distinct paths: Alpine packages install to `/sbin/tini`, Debian/Ubuntu packages install to `/usr/bin/tini`, and scratch or distroless images require multi-stage binary copying. The agent must inspect the Dockerfile `FROM` directive and declare the correct install pattern without hallucinating binary paths.

Terminal Command
# Inspect current Dockerfile base image grep -E '^FROM' Dockerfile
Dockerfile.snippet
# For Alpine Linux:
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]

# For Debian / Ubuntu:
RUN apt-get update && apt-get install -y --no-install-recommends tini \
    && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini", "--"]
Production Pro-Tip

Prefer distribution package managers over unverified curl binary downloads to preserve reproducible SBOMs and package checksum integrity.

Sandbox Gotcha

Do not omit `--` after the Tini binary path. Without `--`, any runtime flags passed by users might be erroneously parsed as Tini flags rather than arguments to your entrypoint script.

3

Intent Matching & Trigger Invocation

Invoke the skill deterministically using frontmatter trigger phrases in Codex, Claude Code, or Cursor.

Agent systems match tasks to installed skills through semantic trigger mapping. Using natural phrases like 'setup tini docker init' or 'reap zombie processes container' directly activates the SOP instructions, bypassing generic LLM improvisation.

Terminal Command
# Example invocation command within Claude Code CLI claude "Refactor the production Dockerfile to setup tini docker init and ensure graceful shutdown"
agent_invocation.sh
# Triggering the SOP via agent CLI
claude "Execute SOP: setup tini docker init for worker service, ensure zombie process reaping and POSIX SIGTERM signal forwarding."
Production Pro-Tip

Combine the skill trigger phrase with the exact service or file name to focus the agent's edit diff precisely on the target Dockerfile.

Sandbox Gotcha

Avoid vague commands like 'fix docker'. Agents will often revert to using simple bash entrypoint wrappers without init systems unless explicit trigger phrases are passed.

4

Verification, Process Hierarchy & Signal Quality Gate

Execute deterministic validation checks to guarantee Tini occupies PID 1 and sub-processes terminate cleanly.

After the agent modifies the Dockerfile, execute a validation pipeline. Build the image, start a container detached, verify the process tree via `ps -ef`, issue a SIGTERM via `docker stop -t 3`, and inspect container exit codes. An exit code of 0 or 143 indicates correct graceful termination; exit code 137 indicates a timeout and forced SIGKILL.

Terminal Command
docker build -t test-init:local . && docker run -d --name test-init-container test-init:local && docker exec test-init-container ps -ef && docker stop -t 3 test-init-container && docker inspect test-init-container --format='{{.State.ExitCode}}'
verify_init.sh
#!/usr/bin/env bash
set -euo pipefail

CONTAINER_ID=$(docker run -d test-init:local)
trap 'docker rm -f $CONTAINER_ID >/dev/null 2>&1' EXIT

PID1_NAME=$(docker exec "$CONTAINER_ID" ps -o comm= 1 | tr -d ' ')
if [[ "$PID1_NAME" != *"tini"* ]]; then
  echo "Verification FAILED: PID 1 is '$PID1_NAME', expected tini."
  exit 1
fi
echo "Verification PASSED: PID 1 is $PID1_NAME."
Production Pro-Tip

Ensure entrypoint shell scripts end with 'exec "$@"' so the spawned application takes the PID space directly managed by Tini, preserving process hierarchies.

Sandbox Gotcha

If you see exit code 137 on 'docker stop', your child process is still ignoring SIGTERM or running behind an unmanaged subshell.

Real-World Scenario: Eliminating Zombie Node.js Subprocesses and Fixing 10-Second Deploy Hangs

Tested Trigger Prompt (Feed directly into Codex, Claude, or Cursor):

“We have a Node.js microservice Dockerfile that spawns FFmpeg child processes. In production, we are seeing defunct <zombie> processes accumulating and Docker deployments take 10+ seconds because containers refuse to stop gracefully. Please setup tini docker init, configure zombie process reaping, and ensure SIGTERM is properly forwarded.”

Deterministic Agent Verification Pipeline:
Analyzes the current Dockerfile and detects an Alpine-based Node.js runtime executing CMD ["node", "worker.js"] directly as PID 1.
Injects 'RUN apk add --no-cache tini' into the Docker build layers immediately before copying application assets.
Configures ENTRYPOINT ["/sbin/tini", "--"] and preserves CMD ["node", "worker.js"] using strict JSON exec array syntax.
Validates that the existing custom entrypoint script includes 'exec "$@"' to guarantee signal forwarding from Tini to the Node child process.
Runs an automated test checking container lifecycle to ensure 'docker stop' terminates within 2 seconds with exit code 0 or 143.

Runtime Troubleshooting & Failure Modes

Error: container_linux.go: starting container process caused: exec: "/sbin/tini": stat /sbin/tini: no such file or directory

Root Cause: The Dockerfile base image is Debian or Ubuntu, but the entrypoint referenced the Alpine package path (/sbin/tini), or Tini was omitted from the final stage of a multi-stage build.

Resolution Command / Fix:
RUN apt-get update && apt-get install -y --no-install-recommends tini && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini", "--", "/app/docker-entrypoint.sh"]
Error: Container takes 10+ seconds to stop and exits with code 137 (SIGKILL issued by Docker daemon)

Root Cause: The Dockerfile entrypoint was declared using shell syntax (ENTRYPOINT /sbin/tini -- /entrypoint.sh) instead of exec array syntax, causing /bin/sh to intercept signals, or the wrapper script failed to use 'exec' before launching the app.

Resolution Command / Fix:
# In Dockerfile:
ENTRYPOINT ["/sbin/tini", "--", "/entrypoint.sh"]
CMD ["node", "index.js"]

# In /entrypoint.sh (last line must use exec):
exec "$@"

Frequently Asked Questions (Tini Lightweight Init System & Zombie Process Reaping SOP)

Q:Can I use Tini Lightweight Init System & Zombie Process Reaping across Codex, Claude Code, and Cursor simultaneously?

Yes. The SKILL.md specification is fully runtime-agnostic. Placing it in your repository's `.agents/skills/` directory allows Codex, Claude Code CLI, Cursor, and Windsurf to consume the exact same operational boundaries, entrypoint syntax guidelines, and verification tests.

Q:How does Tini Lightweight Init System & Zombie Process Reaping prevent context window overflow during long agent sessions?

By providing deterministic execution templates (e.g., precise package manager syntax and exec array forms) directly in the skill specification, the agent does not waste prompt tokens generating speculative shell scripts, debating PID 1 theory, or engaging in multi-turn trial-and-error debugging.

Q:What is the difference between Docker's '--init' runtime flag and baking Tini into the Dockerfile?

Docker's runtime flag (`docker run --init`) mounts an internal tiny init binary on the host without modifying the image. However, baking Tini into the Dockerfile via this skill guarantees that the image runs with PID 1 zombie reaping across all environments, including Kubernetes clusters, Amazon ECS, and Nomad, where the host `--init` flag is unavailable.

Ready to equip your autonomous agent with Tini Lightweight Init System & Zombie Process Reaping?

Copy the complete audited SKILL.md specification or download the 1-click zip bundle directly from our verified registry.

Get 1-Click Install Spec