docker stop gửi SIGTERM, chờ 10 giây (mặc định) rồi gửi SIGKILL. Treo đủ 10 giây nghĩa là không ai xử lý SIGTERM. Ba nguyên nhân thường gặp:
1. PID 1 là shell — dùng shell form hoặc script start.sh không exec, nên sh giữ PID 1 và không forward tín hiệu.
2. PID 1 là npm / yarn / gunicorn wrapper — process cha nhận tín hiệu nhưng không truyền cho con đúng cách.
3. App không đăng ký handler — không có graceful shutdown, cứ chạy tới khi bị kill.
Cách sửa:
dockerfile
CMD ["node", "server.js"] # app is PID 1, not npm/shjs
process.on('SIGTERM', () => {
server.close(() => process.exit(0)) // stop accepting, drain in-flight requests
})Nếu buộc phải có process cha (chạy nhiều tiến trình, cần reap zombie), dùng init nhỏ: docker run --init hoặc nhúng tini làm ENTRYPOINT.
Cần thời gian drain dài hơn thì docker stop -t 30 (Kubernetes: terminationGracePeriodSeconds).