- Notifications
You must be signed in to change notification settings - Fork 23
Description
Is there an existing issue for this?
- I have searched the existing issues
Current Behavior
In containerized environments (e.g., Docker/Kubernetes), npm run <script> spawns /bin/sh -c "<script>". On pod termination, SIGTERM is delivered to PID 1 and forwarded to npm, which forwards it to its direct child (the shell). On some shells (e.g., ash/dash), the shell exits promptly on SIGTERM without waiting for its grandchild process (node). npm then exits because its direct child has exited; PID 1 considers the container finished; the container stops before the Node.js app completes its graceful shutdown (e.g., server.close() / cleanup). This effectively bypasses terminationGracePeriodSeconds.
Expected Behavior
npm should have an opt-in mechanism to wait for the actual target process (e.g., node) so that graceful shutdown reliably completes on Kubernetes. The default behavior should remain unchanged for compatibility, but an option should exist to:
- Direct exec (Unix): If the script is a simple single command without shell metacharacters, spawn it directly (no
/bin/sh). - Exec-replace (Unix): Keep the shell but automatically
exec-replace it so the shell becomes the target process.
Possible surfacing to be coordinated with npm/cli (for context): a CLI flag like npm run --prefer-direct-exec, an .npmrc config, or an env var. Windows can keep the current behavior.
Steps To Reproduce
- Environment: Linux container (e.g., node:18-slim), PID 1 = dumb-init or tini, orchestrated by Kubernetes.
- package.json:
"start": "node index.js"(noexec). - Run the pod and terminate it via
kubectl delete pod(sends SIGTERM). - Observe:
/bin/sh(ash/dash) exits promptly on SIGTERM; npm exits because its direct child is gone; the container stops before the Node app finishes its graceful shutdown work.
Environment
- npm: 10.x
- Node: 18.x
- OS: Linux container
- PID 1: dumb-init (or tini)
- platform: Kubernetes (SIGTERM on pod termination via
kubectl delete pod)