Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 6, 2022 03:37 pm GMT

Why Ship NodeJS Containers With NPM?

There is a number of great guides on "containerizing" NodeJS applications, including this one from Snyk. However, I am yet to see a resource recommending to omit NPM from the final container image.

Let's say I have the following "dummy" application:

index.js

const express = require('express')const app = express()app.get('*', function (req, res) {  res.send('bla bla bla')})app.listen(3000)

package.json

{  "name": "test",  "version": "1.0.0",  "main": "index.js",  "scripts": {    "start": "node index.js"  },  "dependencies": {    "express": "^4.17.2"  }}

One common way to structure a Dockerfile for this app would be using two stage build. First stage, installing dependencies; and second creating the final image. Both stages are using Alpine image with pre-installed NodeJS and NPM. With our simple app, we can even omit the first step, but let's pretend we need it.

bad.Dockerfile

# Build stageFROM node:16-alpine3.15 as build# Install dependenciesWORKDIR /COPY package-lock.json .COPY package.json .RUN npm ci --production# Final stageFROM node:16-alpine3.15 as final# Setup applicationRUN mkdir -p /app/simple-serverWORKDIR /app/simple-serverCOPY . .COPY --from=build node_modules node_modules# Run applicationENTRYPOINT ["node", "index.js"]

As you can see NPM will be shipped with the final container image. So what's the problem here?

The issue is the final image will have the dependency that is not used, but you would have to maintain it.

Not a big deal? It actually is, and can potentially become a blocker preventing to ship your application to production (or other environment depending on security controls in place). A good example is CVE-2021-3807. There is a GitHub Issue open, where engineers complaining how vulnerability presented in NPM blocks them in one or another way.

The solution here is simple - omit NPM from your final image. In Docker multi-stage build, it would look very similar to the bad example. The main difference is the final image is bare Alpine, and only NodeJS is installed as build step.

good.Dockerfile

# Build stageFROM node:16-alpine3.15 as build# Install dependenciesWORKDIR /COPY package-lock.json .COPY package.json .RUN npm ci --production# Final stageFROM alpine:3.15 as final# Upgrade APKRUN apk --no-cache add --upgrade nodejs~16# Setup applicationRUN mkdir -p /app/simple-serverWORKDIR /app/simple-serverCOPY . .COPY --from=build node_modules node_modules# Run applicationENTRYPOINT ["node", "index.js"]

Not much else to say here. If you still have NPM in your final container image, ask yourself why!

Thank you for reading this article, and I would like to see the feedback on this one! Please let me know in comments what are YOUR legitimate reasons for having NPM in the final container image.


Original Link: https://dev.to/hi_artem/why-ship-nodejs-containers-with-npm-33pp

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To