Sign inSign up

runtimenode/runtime-node

By runtimenode

•Updated 5 months ago

Secure, Distroless, Multi-Arch Node.js Runtime. Built from Scratch, 0 Vulnerabilities, <50MB.

Image
Security
Languages & frameworks
Developer tools
1

10K+

runtimenode/runtime-node repository overview

Icon

⁠Runtime Node

Secure, Distroless, Multi-Arch Node.js Runtime. Built from Scratch.

License Latest Release Platforms Vulnerabilities Image Size Docker Pulls Node.js


Runtime Node is a production-grade Docker base image that ships only what Node.js actually needs to run — and nothing more. No shell. No package manager. No OS utilities. Just Node.js and the minimum set of components required to run it reliably in production.

Built with a FROM scratch runtime stage, the image is assembled by extracting only the required binaries and shared libraries from the official Alpine Node.js image instead of inheriting a full operating system. The result is a smaller, cleaner runtime image with a minimal attack surface.


⁠Why Runtime Node?

Most Node.js Docker images ship with far more than your application needs at runtime. Shells, package managers, and system utilities do not help your app run — they just add extra surface area.

Runtime Node enforces a distroless runtime contract: if a component is not required to execute Node.js, it is not in the image. Every release is verified by automated integrity checks before publication.


⁠Key Features

FeatureDetail
BaseFROM scratch — no OS userland, no shell
Current Main LineNode.js 26.1.0
Maintained LineNode.js 24.15.0 and 25.9.0
NODE_ENVproduction (baked in)
TZUTC (baked in)
Timezone DatabaseIANA tzdata included
Image Size<50 MiB
Architectureslinux/amd64, linux/arm64
ShellNone
Package ManagerNone
CA CertificatesIncluded
DNS Resolutionnsswitch.conf included
Provenance & SBOMGenerated on every release

⁠How Does It Compare?

node:latestnode:alpineruntimenode/runtime-node
Approx. compressed amd64 size~388 MiB~57 MiB<50 MiB
BaseDebian-basedAlpine LinuxFROM scratch
Shell✅✅❌ None
Package Manager✅✅❌ None
OS userlandFullMinimalNone
NODE_ENV=production preset❌❌✅
TZ=UTC preset❌❌✅
Provenance & SBOM❌❌✅

Approximate compressed linux/amd64 sizes from the Docker Hub API on March 30, 2026.


⁠Quickstart

⁠Pull the Image
# Docker Hub — latest
docker pull runtimenode/runtime-node:latest

# Docker Hub — versioned (recommended for production)
docker pull runtimenode/runtime-node:v<major>.<minor>.<patch>-node<node_version>

# GitHub Container Registry — latest
docker pull ghcr.io/runtimes-node/runtime-node:latest

# GitHub Container Registry — versioned (recommended for production)
docker pull ghcr.io/runtimes-node/runtime-node:v<major>.<minor>.<patch>-node<node_version>

For available tags, see the Tags tab⁠ or the Releases page⁠ on GitHub.

Docker registries normalize + to - in tag names. The canonical GitHub release is v<major>.<minor>.<patch>+node<node_version>; the published registry tag is v<major>.<minor>.<patch>-node<node_version>.

⁠Use in a Dockerfile
# Build stage — match the current runtime line
FROM node:<node_version>-alpine3.23 AS builder

WORKDIR /dist

COPY ./ ./

RUN npm ci --omit=dev --no-cache

# Runtime stage — distroless, production-ready
FROM runtimenode/runtime-node:v<major>.<minor>.<patch>-node<node_version>

# Copy your production build artifacts only
COPY --from=builder --chown=1000:1000 --chmod=550 dist/ /app/

# Expose any port needed to run the JavaScript file, for example 5500
EXPOSE 5500

#Switch to non-root user inside a group
USER 1000:1000

# No shell is available — invoke Node directly using exec form
ENTRYPOINT ["/usr/local/bin/node", "/app/index.js"]

If you are targeting the Node.js 24 LTS line instead, pair node:24.<minor_node_version>.<patch_node_version>-alpine3.23 with runtimenode/runtime-node:v1.<minor>.<patch>-node24.<minor_node_version>.<patch_node_version>.

Because the image has no shell, your ENTRYPOINT must use exec form (JSON array syntax) and reference the Node.js binary by its absolute path: /usr/local/bin/node.


⁠Tags and Versioning

GitHub release tags follow the pattern v<major>.<minor>.<patch>+node<node_version>.

Published registry tags use the normalized form v<major>.<minor>.<patch>-node<node_version>.

Example:

  • GitHub release: v2.2.0+node25.9.0
  • Docker Hub / GHCR tag: v2.2.0-node25.9.0

The project semver is independent of Node.js semver. A Node.js major version bump triggers a major image bump. A Node.js minor or patch bump triggers a minor image bump. All other changes trigger a patch bump.

⁠Active Release Lines

As of May 11, 2026:

LineCurrent GitHub ReleaseCurrent Registry TagStatus
v3.x.x+node26.x.xv3.1.0+node26.1.0v3.1.0-node26.1.0Active — tracks latest
v2.x.x+node25.x.xv2.2.0+node25.9.0v2.2.0-node25.9.0Maintained
v1.x.x+node24.x.xv1.3.0+node24.15.0v1.3.0-node24.15.0Maintained
  • The floating latest tag currently points to the latest release⁠.
  • The v3.x.x+node26.x.x line is the current main release line
  • The v2.x.x+node25.x.x line is the Node.js 25 maintenance line.
  • The v1.x.x+node24.x.x line is the Node.js 24 LTS maintenance line.

For production deployments, always pin to a specific versioned registry tag rather than latest.


⁠What Is Inside

The final image contains only the components required for Node.js to operate correctly in production:

  • Node.js binary at /usr/local/bin/node
  • CA certificates for outbound TLS at /etc/ssl/certs
  • Timezone database (IANA tzdata) at /usr/share/zoneinfo with TZ=UTC by default
  • Runtime shared libraries — ld-musl, libstdc++, libgcc_s
  • Writable /tmp with sticky-bit permissions (1777)
  • DNS config — minimal nsswitch.conf at /etc/nsswitch.conf

⁠What Is Not Inside

By design, the image does not include:

  • A shell — /bin/sh, /bin/bash, or any equivalent
  • A package manager — apk, apt, yum, or any equivalent
  • OS utilities — curl, wget, ps, ls, or any equivalent

If you need build tools or debugging utilities, use a separate builder stage. Do not expect to exec into this container — it has no shell to execute.


⁠Runtime Defaults

Two environment variables are baked into every image:

  • NODE_ENV=production
  • TZ=UTC

The timezone can still be overridden at runtime because the timezone database is included.


⁠Multi-Architecture Support

Every release is built for both linux/amd64 and linux/arm64 with provenance attestations and an SBOM. The same image tag works across both architectures — Docker automatically pulls the correct variant for your platform.


⁠Security

Runtime Node is built to minimize the attack surface at every layer:

  • FROM scratch base
  • No shell or package manager in the final image
  • Automated distroless integrity checks run before release
  • Minimal runtime contents only
  • Provenance and SBOM generated on every release

To report a vulnerability, use GitHub Security Advisories⁠. Do not open a public GitHub issue for security reports. See SECURITY.md⁠ for the full disclosure process.


⁠Registries

RegistryImage
Docker Hubruntimenode/runtime-node
GitHub Container Registryghcr.io/runtimes-node/runtime-node

⁠Resources


⁠License

Runtime Node is licensed under the Apache License 2.0⁠. See LICENSE⁠ for details.

Tag summary

Content type

Image

Digest

sha256:d60b2a4a7…

Size

52.6 MB

Last updated

5 months ago

docker pull runtimenode/runtime-node