npm package versions are not pinned

Installing npm packages without pinned versions can change Docker build results.

Description

A command such as npm install sax can install a different version as the registry changes. Rebuilding the same Dockerfile may therefore produce different results.

Even small Node.js dependency updates can change behavior. Explicit versions help keep unexpected updates out of deployment images.

Potential impact

  • Different npm package versions can be installed at different build times.
  • Unexpected updates can cause application errors.
  • Test and production dependency sets can differ.

Remediation

  • Specify package versions, as in npm install sax@0.1.1.
  • Pin versions for global installations too.
  • Install project dependencies with a reviewed lock file and npm ci, and manage transitive as well as direct dependency changes.

Examples

Supply an exact, reviewed version compatible with the Node.js environment through ANGULAR_CLI_VERSION. A tag or version range is not an exact pin. sax@0.1.1 is a historical syntax example, not a production recommendation. Pin Git dependencies to a verified commit rather than a range such as #semver:^5.0.

Before

dockerfile
FROM node:22
RUN npm install sax
RUN npm i -g @angular/cli

After

dockerfile
FROM node:22
ARG ANGULAR_CLI_VERSION
RUN npm install sax@0.1.1
RUN test -n "$ANGULAR_CLI_VERSION" && npm i -g "@angular/cli@${ANGULAR_CLI_VERSION}"

Explanation:

  • Before: Package versions are unspecified and build results can change.
  • After: Explicit versions control changes to the named dependencies.

References