Skip to main content

PG008: Use an init process (tini) for proper signal handling and zombie reaping

Info Reliability

Why This Matters

When your application runs as PID 1 inside a container, the kernel treats it differently: SIGTERM has no default handler and is silently ignored. This means `docker stop` and Kubernetes graceful shutdown signals do nothing. The container just hangs for the full terminationGracePeriodSeconds (default 30s) until it is forcefully killed with SIGKILL. On top of that, PID 1 is responsible for reaping zombie child processes by calling wait(). Most applications never do this, so orphaned children accumulate as zombies until the PID table is exhausted (~32,768 entries), at which point fork() fails and the container becomes unresponsive. A lightweight init process like tini (~25 KB) or dumb-init sits as PID 1, forwards signals to your application, and reaps zombies automatically. Docker provides a --init flag for local development, but Kubernetes has no equivalent runtime flag, so the init binary must be installed in the image.

How to Fix

Install tini and use it as the ENTRYPOINT. Your application command moves to CMD.

Before (incorrect)

CMD ["node", "server.js"]

After (correct)

RUN apt-get update && apt-get install -y --no-install-recommends tini && \
    rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["node", "server.js"]

Rule Details

Rule Code
PG008
Severity
Info
Category
Reliability

Related Rules