Runtime Node is a production-grade Node.js runtime image designed for teams that care about security, consistency, and fast deployments. It removes everything that is not required to run Node.js and ships only the minimal runtime surface you need in production.
Use it when you want:
- A smaller, safer runtime image with a reduced attack surface.
- Deterministic production behavior with no unexpected system tools.
- A clean separation between build-time and runtime concerns.
Modern Node.js services do not need a full OS. Runtime Node keeps the runtime lean while preserving the essentials that real production workloads rely on.
Highlights:
- Distroless and built from
scratchfor minimal attack surface. - Includes Node.js, CA certificates, and timezone data for real-world workloads.
- Multi-architecture ready for
linux/amd64andlinux/arm64deployments. - Clear, explicit runtime contract: no shell, no package manager, no OS utilities.
| Outcome | Runtime Node delivers | Why it matters |
|---|---|---|
| Smaller runtime surface | Distroless scratch runtime with only Node, certs, tzdata, and minimal libs |
Less to patch, scan, and maintain in production. |
| Predictable production defaults | NODE_ENV=production and TZ=UTC are baked into the image |
Fewer environment surprises across fleets. |
| Clear build/runtime split | Build elsewhere, ship only runtime artifacts | Faster deploys and simpler rollbacks. |
| Multi-arch readiness | linux/amd64 and linux/arm64 |
Consistent rollout across heterogeneous fleets. |
| Use case | Best-fit image | Rationale |
|---|---|---|
| Production runtime for Node apps | Runtime Node | Distroless runtime, minimal surface, explicit defaults. |
| General-purpose Node base | Official node:<version> |
Default image designed for broad use, based on buildpack-deps with common Debian packages. |
| Smallest official footprint | Official node:<version>-alpine |
Alpine-based variant optimized for size. |
| Minimal Debian userland | Official node:<version>-slim |
Slim variant with only minimal packages needed to run Node. |
These are the two primary size-focused official variants documented by the Node Docker Official Image: node:<version>-alpine and node:<version>-slim.
| Image | Base | Distroless | OS userland present | Primary intent |
|---|---|---|---|---|
| Runtime Node | scratch |
Yes | No | Production runtime only. |
node:<version>-alpine |
Alpine Linux | No | Yes | Smallest official base; add only what you need. |
node:<version>-slim |
Debian-based (slim) | No | Yes | Minimal packages required to run Node. |
- Versioned (Recommended for Production):
# Pull the versioned published tag
docker pull runtimenode/runtime-node:v<image_semver>+node<node_version>- Latest (Not Recommended for Production):
# Pull the latest published tag
docker pull runtimenode/runtime-node:latest- Versioned (Recommended for Production):
# Pull the versioned published tag
docker pull ghcr.io/runtimes-node/runtime-node:v<image_semver>+node<node_version>- Latest (Not Recommended for Production):
# Pull the latest published tag
docker pull ghcr.io/runtimes-node/runtime-node:latest- Versioned (Recommended for Production):
# Use the same Node.js version as your final runtime stage base image
FROM node:<node_version>-alpine AS builder
WORKDIR /dist
COPY ./ ./
RUN npm ci --omit=dev --no-cache
# Use the same Node.js version as your builder stage base image
FROM runtimenode/runtime-node:v<image_semver>+node<node_version>
# Copy your production build artifacts only
COPY --from=builder --chmod=555 dist/ /app/
# No shell is available, so invoke Node directly
ENTRYPOINT ["/usr/local/bin/node", "/app/server.js"]- Latest (Not Recommended for Production):
FROM node:alpine AS builder
WORKDIR /dist
COPY ./ ./
RUN npm ci --omit=dev --no-cache
FROM runtimenode/runtime-node:latest
# Copy your production build artifacts only
COPY --from=builder --chmod=555 dist/ /app/
# No shell is available, so invoke Node directly
ENTRYPOINT ["/usr/local/bin/node", "/app/server.js"]Runtime Node is assembled in a builder stage and copied into a scratch runtime. The final image includes:
- Node.js binary at
/usr/local/bin/node. - CA certificates for outbound TLS in
/etc/ssl/certs. - Timezone database in
/usr/share/zoneinfowithTZ=UTCby default. - Minimal runtime libraries for the Node.js binary (
ld-musl,libstdc++,libgcc). - A writable
/tmpmount point with sticky bit permissions (1777). - Minimal DNS config in
/etc/nsswitch.conf.
By design, the runtime image does not include:
- A shell (
/bin/sh,/bin/bash). - A package manager (
apk,apt,yum). - Common OS utilities (
curl,wget,ps,ls).
If you need build tools or debugging utilities, use a separate build stage or a dedicated debug image.
Runtime Node sets sensible production defaults:
NODE_ENV=productionTZ=UTC
Applications that need a different timezone can set TZ at runtime (timezone data is included).
- Supported platforms:
linux/amd64,linux/arm64. - Registries: Docker Hub and GitHub Container Registry (GHCR).
Tags follow the pattern:
v<image_semver>+node<node_version>(example:v1.0.0+node24.13.1)latesttracks the most recent release.
Check the GitHub Releases page for the current tag and Node.js version.
Runtime Node is built to minimize the attack surface:
- The runtime is
scratch-based and distroless. - Only the runtime components required for Node.js are included.
- No shell or package manager exists in the final image.
Report security issues privately. See SECURITY.md for the disclosure process.
We are committed to a respectful, inclusive community. Please read and follow CODE_OF_CONDUCT.md.
We welcome contributions that keep the runtime secure, minimal, and production-focused. See CONTRIBUTING.md for guidelines and workflow details.
Runtime Node exists because of a small set of outstanding open-source projects that power the runtime and the delivery pipeline.
Node.js — The JavaScript runtime this image is built to ship. The Node.js binary and its required shared libraries (libstdc++, libgcc, musl libc) are extracted from the official node Docker image, maintained by the Docker community and the Node.js project.
Alpine Linux — Minimal base distribution that underpins the official node:<version>-alpine builder image.
musl libc — C standard library required by the Node.js binary in the Alpine-based builder image and copied into the runtime.
libstdc++ and libgcc — GCC runtime libraries required by the Node.js binary and copied from the official node image.
tzdata — IANA timezone database, installed to ensure production timezones resolve correctly.
ca-certificates — Trusted certificate bundle required for outbound TLS connections.
GitHub Actions — Automation platform that runs the CI/CD workflows for linting, build, and release.
Docker Engine / BuildKit — Build backend used by Docker Buildx to assemble multi-platform images.
Docker Buildx — CLI plugin used to drive multi-platform builds.
QEMU — Emulator used to enable cross-platform builds for non-native architectures.
Docker Hub and GitHub Container Registry — Registries used to publish and distribute images.
Hadolint — Dockerfile linter used in the PR pipeline to enforce best practices and catch issues before they reach the image.
docker/build-push-action — GitHub Action used to build and push multi-platform images with provenance and SBOM support.
docker/metadata-action — GitHub Action used to extract and generate OCI-compliant image tags and labels from Git references.
docker/login-action — GitHub Action used to authenticate with Docker Hub and the GitHub Container Registry during the deployment workflow.
docker/setup-qemu-action — GitHub Action used to enable QEMU emulation for multi-platform builds.
docker/setup-buildx-action — GitHub Action used to configure Docker Buildx for advanced multi-platform build capabilities.
actions/checkout — GitHub Action used to check out the repository code in every workflow job.
| Name | GitHub | Role | |
|---|---|---|---|
| Amnoor Brar | @Amnoor | Creator & Maintainer |
Want to see your name here? Check out CONTRIBUTING.md.
Runtime Node is licensed under the Apache-2.0 License. See LICENSE.