Install libatomic so Node.js 25+ works in the runner image and on self-hosted Linux runners - #4640
Open
yooknee wants to merge 2 commits into
Open
Install libatomic so Node.js 25+ works in the runner image and on self-hosted Linux runners#4640yooknee wants to merge 2 commits into
yooknee wants to merge 2 commits into
Conversation
The official Node.js binaries link against libatomic.so.1 starting with Node.js 25 (confirmed with `readelf -d bin/node`: the NEEDED entry is absent in v24.x and present in v25.x and v26.x, on both linux-x64 and linux-arm64). The dotnet/runtime-deps base image does not ship that library, so a workflow that provisions Node with actions/setup-node fails at exec time with: node: error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory Add libatomic1 to the existing apt transaction in the runtime stage. It comes from Ubuntu main (source package gcc-14), so it adds no new repository or trust anchor, ships no executables, and costs ~50 kB installed. Reusing the existing RUN keeps the layer count unchanged and keeps the package lists cleaned up in the same step. Also add a cheap regression test to the docker job so the library cannot silently disappear from the image again. Fixes actions#4591
Non-containerized self-hosted runners hit the same Node.js 25+ failure as the container image: actions/setup-node installs Node into the tool cache, and it cannot start without libatomic.so.1. Install the library from each distribution's own package manager (libatomic1 on Debian/SUSE based, libatomic on Fedora based). This is done best-effort rather than as a hard requirement: the runner itself does not need libatomic today, since the bundled externals/node20 and externals/node24 do not link against it, so a distribution that does not package it must still configure successfully. On failure the script prints an actionable warning naming the package and the error it prevents. For the same reason config.sh is left alone -- gating runner configuration on a library only future Node.js versions need would be a regression. Document the dependency and the reasoning in docs/start/envlinux.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4591
Problem
The official Node.js binaries link against
libatomic.so.1starting with Node.js 25. Neitherthe
mcr.microsoft.com/dotnet/runtime-deps:8.0-noblebase image nor a stock Debian/Ubuntu hostships that library, so any workflow step that provisions a modern Node — most commonly
actions/setup-node— installs successfully and then fails the moment Node is executed:Installing Node is a routine workflow step, so the runner should supply the library rather than
leaving every user to discover the workaround themselves.
Verification
readelf -d bin/nodeon the official tarballs pins the cutover at Node 25, on both architectures:libatomic.so.1inNEEDEDexternals/)The base image installs only
ca-certificates, libc6, libgcc-s1, libicu74, libssl3t64, libstdc++6, tzdata, tzdata-legacy, zlib1g—libatomic1is genuinely absent.Changes
images/Dockerfile—libatomic1added to the existing apt transaction in the runtime stage,not a new
RUN, so the layer count is unchanged and the existingrm -rf /var/lib/apt/lists/*still applies.
.github/workflows/build.yml— regression test in thedockerjob so the library cannotsilently drop out of the image again. It runs on both the amd64 and arm64 matrix legs: