- Advanced
- Running containers
How it works
With the exec form of CMD, or exec at the end of a wrapper script, the app itself is PID 1 and gets SIGTERM. stop_grace_period in Compose (docker stop -t) sets how long Docker waits. init: true makes tini PID 1 to forward signals and reap zombies, but it signals its direct child only.
What breaks
A shell as PID 1 ignores SIGTERM: every stop lasts the full grace period and ends with SIGKILL (exit code 137), cutting requests, jobs and transactions in the middle. Under tini, a wrapper shell dies at once (exit code 143) and the app goes with it. Work longer than the grace period is killed too.
In a Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY . .
# exec: node replaces the shell and receives SIGTERM itself.
CMD ["sh", "-c", "node src/migrate.js && exec node src/worker.js"]
See it break, then fix it
Write the Dockerfile or the compose file, type the docker commands, and watch a simulated server run them through reboots, upgrades and traffic. Free to start.