Skip to content

Use a distroless Node.js runtime image - #1938

Open
afoote-mitre wants to merge 3 commits into
devfrom
af/distroless-test
Open

Use a distroless Node.js runtime image#1938
afoote-mitre wants to merge 3 commits into
devfrom
af/distroless-test

Conversation

@afoote-mitre

@afoote-mitre afoote-mitre commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Replace the Alpine-based production image with a multi-stage build using a pinned Node.js builder and a pinned distroless runtime. The resulting image runs as a non-root user, excludes build and development tooling, and retains the existing application startup behavior.

Important Changes

docker/Dockerfile

  • Replaced the single-stage Alpine image with a multi-stage build.
  • Pinned the builder to node:24.18.0-trixie-slim by immutable digest.
  • Pinned the distroless Node.js 24 Debian 13 runtime by immutable digest.
  • Installed build tools only in the builder stage.
  • Generated OpenAPI documentation during the build.
  • Pruned development dependencies before copying modules into the runtime.
  • Preserved the generated CA certificate bundle for custom certificate support.
  • Runs the application as the distroless non-root user with UID 65532.

src/scripts/start.js

  • Added a shell-free startup entrypoint compatible with distroless.
  • Preserved development, staging, integration, and production environments.
  • Preserved the existing prod-staging and adp-test mappings to production.
  • Rejects unsupported application environments.
  • Prevents startup side effects when imported by test and coverage discovery.

test/unit-tests/scripts/startTest.js

  • Added coverage for supported environments, deployment aliases, and unsupported environment rejection.

package.json and package-lock.json

  • Moved node-dev, replace-in-file, and swagger-autogen to development dependencies so they are excluded from the production runtime.

src/swagger.js and api-docs/openapi.json

  • Changed the OpenAPI server URL to the deployment-independent /api path.
  • Avoids embedding a development hostname in the generated production artifact.

Testing

Build container and ensure all unit and integration tests pass.

Notes

  • Both Docker base images are pinned by immutable multi-platform image digest for reproducible builds while retaining supported architecture selection.
  • Runtime environment variables and credentials remain externally configurable rather than being embedded in the image.

@afoote-mitre
afoote-mitre requested a review from david-rocca July 22, 2026 19:17
@afoote-mitre afoote-mitre self-assigned this Jul 22, 2026
Comment thread docker/Dockerfile Outdated
Comment thread docker/Dockerfile Outdated
Comment thread src/scripts/start.js
@afoote-mitre
afoote-mitre marked this pull request as ready for review July 23, 2026 18:40
@afoote-mitre
afoote-mitre requested a review from david-rocca July 23, 2026 18:43
@david-rocca

Copy link
Copy Markdown
Collaborator

I would like to see this in by 2.8.6 ish

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants