Security Concepts

Is the Node Docker Image Safe? What Our Scanner Found

Published July 12, 2026 · 6 min read

Node is one of the most common application base images in production, which makes “is the node Docker image safe” worth checking before you ship it. We scanned node:22 and its Alpine variant with ScanRook and looked past the headline number to what it actually means.

Is the node Docker image safe — container image safety series

The verdict

Mostly yes, but the default tag is the wrong one for a production runtime. node:22 bundles a full Debian build environment so that native npm modules can compile on install, and that toolchain is where the overwhelming majority of the 30,726 findings in our scan live — not in the Node.js runtime itself. The fix is architectural, not a patch: build with the full tag, then ship on node:22-alpine or a distroless runtime image that never had a compiler in it to begin with.

What we found scanning node:22

We exported the image with docker save and scanned it with ScanRook, which matches every installed package against OSV, NVD, and vendor advisory data:

TagTotalCriticalHighMediumLow
node:2230,7261,7948,86717,1331,058
node:22-alpine306231411348

ScanRook v1.14.2, warm-cache scan, 2026-07-04. Counts change as new advisories publish.

Grouped bar chart of ScanRook severity counts. node:22: 30,726 findings total, 1,794 critical, 8,867 high, 17,133 medium, 1,058 low. node:22-alpine: 306 findings total, 23 critical, 141 high, 134 medium, 8 low.node:2230,726 findings totalCritical1,794High8,867Medium17,133Low1,058node:22-alpine306 findings totalCritical23High141Medium134Low8
The same scan data as a chart — ScanRook v1.14.2 warm-cache scan of node:22 and node:22-alpine, 2026-07-04. Bar length is proportional to the count in each severity bucket, on a scale shared by both tags; the figure beside each tag name is the total finding count that scan reported.

That is roughly a 99% reduction between tags for the same Node.js version. The gap is this large because node:22 ships a complete Debian build environment — GnuPG, dirmngr, the file utility, and compiler tooling — so node-gyp can build native addons at install time. node:22-alpine skips almost all of it.

The CVEs worth knowing about

The top critical findings in node:22 sit in three build-tooling packages:

  • dirmngr — CVE-2005-2023 and CVE-2006-6235.GnuPG's key-fetching helper, present so Debian's package manager can verify signatures. It has no role once your application is running — it only matters if something inside the container invokes apt-get.
  • file — CVE-2004-1304. The Unix file command, used by build scripts to detect binary formats. A two-decade-old advisory against a utility your Node.js process almost certainly never invokes directly.
  • gnupg — CVE-2005-2023 and CVE-2006-6235. The core GnuPG binary that dirmngr depends on, flagged for the same reason: it exists to support build-time package verification, not application logic.

All three are classic build-toolchain findings. Our guide to how vendors backport security patches explains why old CVE IDs like these can already be fixed in a current package even though the reported version number looks ancient.

Which tag should you use?

Use node:22 only as a build stage, and ship on node:22-alpine (or a distroless Node runtime) for production. A multi-stage Dockerfile installs dependencies and compiles native addons in the full image, then copies the built application and node_modules into the slim runtime stage. You get the compiler support you need at build time without shipping it.

The exception is native addons that only build cleanly against glibc; in that case, stay on a Debian-based runtime tag and offset the risk with the hardening steps below. For the broader tradeoffs between base image families, see Alpine vs Debian vs Distroless.

Hardening checklist

  • Use a multi-stage Dockerfile so the build toolchain never reaches your runtime image.
  • Run npm ci --omit=dev in the final stage so dev dependencies aren't shipped either.
  • Run the container as the built-in node non-root user.
  • Pin the image by digest (node@sha256:…) so builds are reproducible.
  • Set NODE_ENV=production to disable dev-only behavior in frameworks that check it.
  • Rebuild and redeploy on a schedule so runtime image patches actually reach you.
  • Scan every build in CI so a base image regression is caught before it ships.

Scan it yourself

Counts drift as new advisories publish, so verify against the exact tag and digest you deploy:

curl -fsSL https://scanrook.io/install.sh | sh
docker save node:22 -o node.tar
scanrook scan node.tar

The full CLI reference, including JSON output and severity gating for CI, is in the docs.

Frequently asked questions

Is the node Docker image safe to use?

Mostly, but the default tag isn't meant for production. node:22 bundles a full Debian build toolchain; node:22-alpine cuts findings by about 99% for the same Node.js version.

Why does node:22 have so many vulnerabilities?

It bundles compiler tooling and Debian package-verification utilities so native npm modules can build on install. Each package carries its own advisory history.

Is node:alpine more secure?

Dramatically: 306 findings vs 30,726 in our scan, about 99% fewer, because it never shipped the build toolchain to begin with.

Should I use a multi-stage build?

Yes. Build and compile native modules in node:22, then copy the application into a node:alpine or distroless runtime stage so the compiler never ships.

Scan your node image with ScanRook

Upload your image tar or scan from the CLI and ScanRook matches every installed package against OSV, NVD, and vendor advisory data — with severity, exploit-probability, and confidence tiers so you can separate real runtime risk from build-time noise.

Related Posts

More on this topic.