chore(docker): build on Node 24 LTS instead of EOL, never-LTS Node 23 - #225
Merged
Conversation
The builder stage pinned node:23.11.1-alpine3.21. Odd-numbered Node releases never become LTS, and 23 reached end-of-life on 2025-06-01, so the toolchain producing every deployed artifact has been receiving no security patches. Moves to node:24.19.0-alpine3.24 — the active LTS line, supported until 2028-04-30 — keeping the existing patch + Alpine-minor pinning so an upstream rebuild cannot change the toolchain under a release. Verified: image builds clean, the static export is byte-identical in size to the previous pin (230 files), and nginx serves /, /docs, /team, /changelog, /faq and /comparison at 200.
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.
What
The builder stage pinned
node:23.11.1-alpine3.21. This moves it tonode:24.19.0-alpine3.24.Why
23 is an odd-numbered Node release. Those never become LTS, and 23 reached end-of-life on 2025-06-01 — so the Node producing every deployed artifact has been receiving no security patches for over a year. Against
nodejs/Release/schedule.json:24 rather than 26, which does not become LTS until 2026-10-28.
The patch + Alpine-minor pinning is kept deliberately, matching what was there before, so an upstream rebuild cannot change the toolchain under a release.
How this surfaced
Reviewing gofr-dev/gofr#3871, which moves the two website deploy workflows off EOL Node 18. That PR is correct and correctly scoped — its comment notes that the runner's Node governs only
yarn installandyarn refresh-data, becausenext buildruns inside this image against its own pin. Which is exactly the point: the runner-side Node was three years EOL, and the one that actually builds the site was a year EOL and never supported to begin with. The two need fixing separately, and this is the second half.Verification
Not just a build — the image was run and the site actually served.
docker build//docs/team/changelog/faq/comparisonBoth pins were built from the same tree; the export file count is identical, so this is not changing what ships.
Separately confirmed on the runner side, against this repo at
main:yarn install --frozen-lockfileandyarn refresh-databoth succeed on Node 24 (138 team members, 21015 stars, 50 releases fetched), and the data they generate feeds this image build cleanly.sharp@0.32.6— the one native dependency, and the usual casualty of a Node major bump — installs without falling back to a source build.Noticed while verifying, not fixed here
yarn refresh-datarun against a standalone checkout of this repo rewritessrc/data/doc-mtimes.jsonfrom 56 entries to 0.generate-doc-mtimes.mjswalkssrc/app/docsand friends, whose.mdcontent is overlaid from the framework repo after that stage, so there is nothing to timestamp at the point it runs. Node 18 produces the same empty result, so it is not version-related and it is not new.Worth someone confirming whether the deploy job hits this too — if it does, the "Last updated" bylines and
dateModifiedJSON-LD are being blanked on every deploy. Filing as an observation rather than guessing at the fix, since it depends on where the overlay lands relative torefresh-data.