Skip to content

Run the NodeSource setup script as root so the image ships Node 24 and npm - #18

Open
eastagiletracker wants to merge 1 commit into
analyticsMD:mainfrom
eastagiletracker:agile-board/nodesource-setup-needs-root
Open

eastagiletracker wants to merge 1 commit into
analyticsMD:mainfrom
eastagiletracker:agile-board/nodesource-setup-needs-root

Conversation

@eastagiletracker

Copy link
Copy Markdown

This PR proposes running the NodeSource setup script with root privileges so the image ships the Node 24 the Dockerfile asks for, together with npm. We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/423. You can sign in with your GitHub ID to claim ownership of the project.

The defect

The published image ships Ubuntu's nodejs 18.19.1 and no npm at all, rather than the Node 24 the Dockerfile names. Node 18 reached end of life on 2025-04-30.

The OS-packages layer pipes NodeSource's installer straight into bash as the unprivileged runner user:

curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && \
sudo apt-get install -y nodejs

Without root the script cannot write apt's lists. Building the current main prints its complaint and then exits 0 anyway:

2026-08-20 08:18:16 - Installing pre-requisites
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
2026-08-20 08:18:17 - Error: Failed to run 'apt update' (Exit Code: 0)

Because the script exits 0 the && chain continues, and sudo apt-get install -y nodejs is satisfied by Ubuntu 24.04's own package instead. Ubuntu packages npm separately — apt lists it only under Suggested packages — so npm never lands either. The build stays green throughout, which is why this has gone unnoticed: the NodeSource repository has never actually been configured, so 70b05ff ("updated version on nodejs") bumping setup_20.x to setup_24.x changed nothing about the image.

Reproduced at HEAD (e403be3)

$ docker build --platform=linux/amd64 -t ghrunner-head .        # exits 0
$ docker run --rm ghrunner-head node --version
v18.19.1
$ docker run --rm ghrunner-head dpkg-query -W -f='${Version}\n' nodejs
18.19.1+dfsg-6ubuntu5                                           # Ubuntu's build, not NodeSource's
$ docker run --rm ghrunner-head bash -lc 'command -v npm || echo MISSING'
MISSING
$ docker run --rm ghrunner-head bash -lc 'ls /etc/apt/sources.list.d/ | grep -i node || echo "not configured"'
not configured

The change

Pipe the setup script to sudo -E bash -, which is NodeSource's documented invocation, and then assert node --version && npm --version so the layer fails loudly instead of silently installing the wrong runtime. That assertion follows the idiom the Atmos, Terraform, Helm and kubectl layers already use, where each install ends in a version check.

Verification

Rebuilt from this branch, the image is what the Dockerfile asked for:

$ docker run --rm ghrunner-fixed node --version
v24.19.0
$ docker run --rm ghrunner-fixed npm --version
11.17.0
$ docker run --rm ghrunner-fixed dpkg-query -W -f='${Version}\n' nodejs
24.19.0-1nodesource1

The ten tool checks in .github/workflows/test-docker-image.yaml were run against both the HEAD image and this branch's image: ten pass and none fail, identically on both, so atmos, terraform, tfcmt, terraform-docs, infracost, helm, helmfile, kubectl, helm diff and aws are unaffected. git, jq, ssh, unzip, zip, curl, perl and python3 are all still present too.

Those checks were run locally rather than through that workflow, because it pushes the built image to the registry before verifying it and a pull request from a fork has no token to push with — so expect that check to stop at the push step here regardless of this change.

The added assertion is not decorative — putting it on the current unprivileged line turns this silent substitution into a build failure:

#5 20.42 v18.19.1
#5 20.42 /bin/sh: 1: npm: not found
ERROR: process "/bin/sh -c ... node --version && npm --version" did not complete successfully: exit code: 127

One point for your judgement

This moves the runner image from Node 18 to Node 24, which is what the Dockerfile has requested since 70b05ff, but it is still a real change for jobs that have been running on 18, and npm appears where there was none. The defect being fixed is that the setup script has to run as root; which major version you land on is a separate one-character decision on the same line, so please pin it to whatever suits your fleet.

How this was managed

We tracked this change on a board imported from this repository's pull request history (17 stories), and this work is the story Run the NodeSource setup script as root so the image ships Node 24 and npm, which carries the reproduction and the verification above. The full board is at https://eastagiletracker.com/projects/423.

board

If you'd rather not receive contributions like this, reply no-more-prs on this pull request and we won't open any further ones on your repositories.


Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com

The image is meant to ship the Node version the Dockerfile names, but it ships
Ubuntu's nodejs 18.19.1 and no npm at all. The setup script is piped into bash as
the unprivileged runner user, so it cannot write apt's lists:

    E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
    E: Unable to lock directory /var/lib/apt/lists/
    Error: Failed to run 'apt update' (Exit Code: 0)

The script still exits 0, so the && chain continues and apt-get install -y nodejs
is satisfied by the distro package instead. The NodeSource repo has therefore
never been configured, and 70b05ff bumping setup_20.x to setup_24.x changed
nothing about the image.

Pipe to sudo -E bash - per NodeSource's documented install, and assert node and
npm afterwards so the layer fails loudly instead of silently installing the wrong
runtime, matching the version checks the other install layers already run.
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.

1 participant