Node.js / Alpine

Official Node.js getting-started example from the Docker documentation.

← Examples

Source: Docker

5 issues foundHigh: 2Medium: 2Low: 1Recommendations: 1
DockerfileLines with findings are highlighted
SHA-256:
1FROM node:22-alpineHigh
2WORKDIR /app
3COPY . .Medium
4RUN yarn install --productionMedium
5CMD ["node", "./src/index.js"]
Findings
5 issues found
FROM node:22-alpine
High CVEs in base image
The base image has one or more high-severity CVEs according to Docker Scout, and no critical ones. High vulnerabilities are often exploitable and may allow privilege escalation or data exposure. Update to a patched image version or switch to a more secure base image. Note: CVE data is sourced from Docker Scout at the time of the last data rebuild — coverage is not guaranteed to be complete, and a clean result does not confirm the image is free of CVEs.
HighBase Image
Container user
User root
The final container is running under the context of the root user.
# Create a dedicated non-root user and switch to it before CMD/ENTRYPOINT RUN useradd --create-home --shell /bin/bash appuser USER appuser
HighUser
COPY . .
Wildcard COPY
Using COPY with a wildcard can introduce unnecessary files into the image.
COPY src/ /app/src/ # or target a specific file COPY config.json /app/config.json
MediumFile Copy
RUN yarn install --production
yarn install without lockfile enforcement
yarn install is used without --frozen-lockfile or --immutable. Without lockfile enforcement, Yarn may resolve different package versions than those recorded in yarn.lock, producing non-reproducible builds and introducing supply-chain risk. Use yarn install --frozen-lockfile (Yarn Classic) or yarn install --immutable (Yarn Berry) to enforce strict lockfile adherence.
MediumPackage Manager
FROM node:22-alpine
FROM without image digest
The base image is referenced by tag rather than by digest. Tags are mutable — the same tag can be silently updated to point to a different image. Pinning to a digest (e.g. image:tag@sha256:...) guarantees you always build from exactly the image you reviewed. If you rebuild frequently with docker build --pull, the freshness risk is lower — though supply-chain reproducibility still benefits from digest pinning. Note: digest-pinning fixes the image layer but does not protect against newly-discovered CVEs in that layer — vulnerability scanning should still be performed regularly even when digests are in use.
LowBase Image

No HEALTHCHECK defined
No HEALTHCHECK defined in final stage
The final image stage does not define a HEALTHCHECK instruction. Without one, container orchestrators and the Docker daemon cannot distinguish a running container from one that is alive but unhealthy (deadlocked, crashed dependencies, etc.), increasing the risk of traffic being routed to a broken container. Add a HEALTHCHECK CMD instruction that tests whether the application is functioning correctly. Note: if the base image already defines a HEALTHCHECK it will be inherited, but this cannot be verified from the Dockerfile alone.