我阅读了一些关于Docker和Node.js最佳实践的文章,例如 https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md,在 Docker 中容器化 Node.js Web 应用程序的 10 种最佳实践 和 Node 和 NPM 的 Dockerfile 最佳实践。所有这些文章都是至少在2021年编写或更新的,我没有列出2021年之前编写的文章,但有相当多的文章。
它们都反对
我猜这可能是旧版 npm 的情况(尽管我没有测试过),但我已经测试过 node14+npm6 和 node16+npm8,并且我可以验证 npm6/8 不会吞噬这些事件,我的优雅关闭代码会运行。不确定是否是因为 npm 修复了它。
所以唯一的问题是还需要运行一个进程,npm,即 NPM 作为 PID 1 运行。一些文章说这样做的问题是“PID 1 不会响应 SIGINT”,但是我已经验证它不是这种情况。
许多文章(例如这个 nodejs 文档)建议只使用
所以我对于
对于我的应用程序,还有一个要考虑的问题,我的npm脚本有预钩子以使应用程序正确运行,我有
--- 更新 ---
我发现了这个已关闭的npm问题lifecycle: propagate SIGTERM to child 因此他们确实解决了它,但该问题中的最新评论是在2017年,其中说:“是的,这不起作用,至少与bash一起; npm在shell中运行其生命周期进程,而bash不会将SIGTERM转发给其子进程。”
我意识到我只在我的Mac和我们的CentOS服务器上以及基于alpine的docker上进行了测试。这也可能是因为CMD中我使用了exec form,而不是shell form,所以我得到了退出信号。 通过Node.js和Kubernetes优雅地关闭表示他们的alpine映像未使用
它们都反对
CMD ["npm", "run", "start"]
。主要原因是 npm 会吞噬退出信号,如 SIGTERM 和 SIGINT,因此我的 node 应用程序中的优雅关闭代码不会运行。我猜这可能是旧版 npm 的情况(尽管我没有测试过),但我已经测试过 node14+npm6 和 node16+npm8,并且我可以验证 npm6/8 不会吞噬这些事件,我的优雅关闭代码会运行。不确定是否是因为 npm 修复了它。
所以唯一的问题是还需要运行一个进程,npm,即 NPM 作为 PID 1 运行。一些文章说这样做的问题是“PID 1 不会响应 SIGINT”,但是我已经验证它不是这种情况。
许多文章(例如这个 nodejs 文档)建议只使用
CMD [ "node", "server.js" ]
,但是在https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#handling-kernel-signals 中也提到“PID 1 运行的 Node.js 进程将不会响应 SIGINT(CTRL-C)和类似的信号。”,即 nodejs 自己的文档与自身相矛盾(但我确实看到 nodejs 作为 PID 1 响应了 SIGINT)。所以我对于
CMD ["npm", "run", "start"]
或 CMD [ "node", "server.js" ]
的问题感到困惑。对于我的应用程序,还有一个要考虑的问题,我的npm脚本有预钩子以使应用程序正确运行,我有
prestart
npm脚本来使npm start
工作。所以目前我只使用 CMD ["npm", "run", "start"]
,但是我对如何在docker中启动我的节点应用程序的“最佳实践”感到困惑。--- 更新 ---
我发现了这个已关闭的npm问题lifecycle: propagate SIGTERM to child 因此他们确实解决了它,但该问题中的最新评论是在2017年,其中说:“是的,这不起作用,至少与bash一起; npm在shell中运行其生命周期进程,而bash不会将SIGTERM转发给其子进程。”
我意识到我只在我的Mac和我们的CentOS服务器上以及基于alpine的docker上进行了测试。这也可能是因为CMD中我使用了exec form,而不是shell form,所以我得到了退出信号。 通过Node.js和Kubernetes优雅地关闭表示他们的alpine映像未使用
npm start
接收到SIGTERM,而我在alpine3.15上测试可以接收到。
npm run start
的运行方式符合你的预期,那么我认为使用它没有任何问题。更广泛的Unix语句是,进程1必须显式订阅SIGINT和SIGTERM才能接收它们,否则它们将被忽略。 - David MazeCMD ["npm", "run", "start"]
的文章都是错误或过时的,这让我感到困惑。我担心自己在这方面错过了什么,这也是我提出问题的部分原因。 - Qiulang