From e8c2d470b4f14724502938a03e4d6115c22642e9 Mon Sep 17 00:00:00 2001 From: Shubhanshu Shukla <76910689+kshanxs@users.noreply.github.com> Date: Sun, 25 Oct 2026 01:11:16 +0530 Subject: [PATCH] docs(docker): install libatomic1 in the Node.js runtime stage Official Node.js 25+ Linux builds link libatomic, which debian:bookworm-slim and gcr.io/distroless/cc do not include, so the copied binary fails to start. Install libatomic1 in the slim runtime stage and show how to copy the library into a distroless runtime. Closes #3219 Co-Authored-By: Claude Opus 5.5 --- docs/guide/docker.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/guide/docker.md b/docs/guide/docker.md index 11b05dfab8..d4372b97cb 100644 --- a/docs/guide/docker.md +++ b/docs/guide/docker.md @@ -63,6 +63,12 @@ FROM debian:bookworm-slim AS runtime WORKDIR /app ENV NODE_ENV=production +# Official Node.js 25+ Linux builds need libatomic, which slim images do not +# include (nodejs/node#60790). Node.js 24 and older do not need this step. +RUN apt-get update \ + && apt-get install -y --no-install-recommends libatomic1 \ + && rm -rf /var/lib/apt/lists/* + # The exact Node.js from .node-version (official, signature-verified build). COPY --from=build /tmp/node /usr/local/bin/node @@ -83,6 +89,17 @@ Install production dependencies in their own `deps` stage as shown. Running `vp ::: tip Smaller still For a shell-less, minimal-CVE runtime, swap the runtime base for distroless (`gcr.io/distroless/cc`) and keep an `ENTRYPOINT` in vector form. It is glibc based, so the copied Node.js binary remains compatible. + +Distroless has no package manager and does not include `libatomic`, which Node.js 25 and later need. Copy it from the build stage alongside Node.js: + +```dockerfile +# build stage +RUN cp /usr/lib/*-linux-gnu/libatomic.so.1 /tmp/libatomic.so.1 + +# runtime stage +COPY --from=build /tmp/libatomic.so.1 /usr/lib/ +``` + ::: ## Production: static SPA / SSG