From 54e206cde09af4898a8836d6a49e74d5088d3ab0 Mon Sep 17 00:00:00 2001 From: Kevyn Bruyere Date: Wed, 22 Jul 2020 11:38:17 +0200 Subject: [PATCH] Add BP about bootstraping using node instead of npm --- README.md | 7 +-- sections/docker/bootstrap-using-node.md | 62 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 sections/docker/bootstrap-using-node.md diff --git a/README.md b/README.md index cdc071fc..ffc47c45 100644 --- a/README.md +++ b/README.md @@ -1094,11 +1094,12 @@ Bear in mind that with the introduction of the new V8 engine alongside the new E ## ![✔] 8.2. Bootstrap the code using 'node' command, avoid 'npm run' scripts -**TL;DR:** +**TL;DR:** use `CMD ['node','server.js']` to start your app. This prevents problems with child-process, signal handling and avoid creating unnecessary processes. -**Otherwise:** -🔗 [**Read More: Clean npm cache**](/sections/docker/file.md) +**Otherwise:** You'll have hard shutdowns, possibly losing current requests and/or data + +[**Read More: Bootstrap container using node command, avoid npm start**](/sections/docker/bootstrap-using-node.md)


diff --git a/sections/docker/bootstrap-using-node.md b/sections/docker/bootstrap-using-node.md new file mode 100644 index 00000000..e636471d --- /dev/null +++ b/sections/docker/bootstrap-using-node.md @@ -0,0 +1,62 @@ +# Bootstrap container using node command instead of npm + +## One paragraph explainer + +We are used to see code examples where folks start their app using `CMD 'npm start'`. This is a bad practice. The `npm` binary will not forward signals to your app which prevents graceful shutdown (see #716). If you are using Child-processes they won’t be cleaned up correctly in case of unexpected shutdown, leaving zombie processes on your host. `npm start` also results in having an extra process for no benefit. To start you app use `CMD ['node','server.js']`. + +### Code example + +```dockerfile + +FROM node:12-slim AS build +WORKDIR /usr/src/app +COPY package.json package-lock.json ./ +RUN npm ci --production && npm clean cache --force + +CMD ['node', 'server.js'] +``` + +### Antipatterns + +Using npm start +```dockerfile + +FROM node:12-slim AS build +WORKDIR /usr/src/app +COPY package.json package-lock.json ./ +RUN npm ci --production && npm clean cache --force + +# don’t do that! +CMD “npm start” +``` + +Using node in a single string will start a bash/ash shell process to execute your command. That is almost the same as using `npm` + +```dockerfile + +FROM node:12-slim AS build +WORKDIR /usr/src/app +COPY package.json package-lock.json ./ +RUN npm ci --production && npm clean cache --force + +# don’t do that, it will start bash +CMD "node server.js" +``` + +Starting with npm, here’s the process tree: +``` +$ ps falx + UID PID PPID COMMAND + 0 1 0 npm + 0 16 1 sh -c node server.js + 0 17 16 \_ node server.js +``` +There is no advantage to those two extra process. + +Sources: + + +https://maximorlov.com/process-signals-inside-docker-containers/ + + +https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#handling-kernel-signals