Skip to content

fix(docker): move published image to Node 24 LTS, not the EOL Node 25 - #73

Merged
karlwaldman merged 1 commit into
mainfrom
chore/dockerfile-node-24-lts
Aug 22, 2026
Merged

fix(docker): move published image to Node 24 LTS, not the EOL Node 25#73
karlwaldman merged 1 commit into
mainfrom
chore/dockerfile-node-24-lts

Conversation

@karlwaldman

Copy link
Copy Markdown
Member

Replaces #72.

The finding

Dependabot #72 proposed node:22-alpinenode:25-alpine and CI went green.
Node 25 reached end of life on 2026-06-01 — 82 days before that PR was opened.

Verified against the authoritative source
(nodejs/Release schedule.json),
read live on 2026-08-22:

line LTS maintenance end status today
v22 (Jod) 2024-10-29 2025-10-21 2027-04-30 supported (current pin)
v24 (Krypton) 2025-10-28 2026-10-20 2028-04-30 Active LTS ← this PR
v25 never 2026-04-01 2026-06-01 EOL (#72 proposed this)
v26 2026-10-28 2027-10-20 2029-04-30 future LTS

Merging #72 would have pinned the published container to a runtime that
receives no further security patches.

Why CI did not catch it

live-tests.yml and publish.yml exercise the packed npm artifact on Node
18/20/22/24. Nothing in CI builds the Dockerfile, so the base-image major is
unverified by construction — the seven green checks on #72 were all true and
none of them was about the thing being changed.

The container is a real distribution surface: server.json registers the npm
stdio package, but registry scanners (Glama, etc.) build this Dockerfile from
the repo.

Changes

  1. Dockerfile — both stages node:22-alpinenode:24-alpine, pinned by
    digest sha256:d32cdf61… (resolved from the Docker Hub registry API; OCI
    image index, amd64/arm64/s390x).
  2. .github/dependabot.yml — ignore version-update:semver-major for
    node in the docker ecosystem, with the EOL history in the comment. Digest
    and minor/patch refreshes on the pinned major still flow. Bump to v26
    deliberately when it becomes Active LTS on 2026-10-28.

Verification (local, 2026-08-22)

$ docker build --build-arg SOURCE_COMMIT=$(git rev-parse HEAD) \
    --build-arg SOURCE_DATE_EPOCH=1755820800 -t opa-mcp-node24-test:local .
  ... exporting manifest list ... DONE

$ docker run --rm --entrypoint node opa-mcp-node24-test:local --version
v24.19.0

$ printf %s\\n <initialize request> | docker run --rm -i opa-mcp-node24-test:local
{"result":{"protocolVersion":"2024-11-05",
 "capabilities":{"tools":{"listChanged":true},"resources":{"listChanged":true},
 "prompts":{"listChanged":true}},
 "serverInfo":{"name":"oilpriceapi","version":"3.2.3"}, ...},"jsonrpc":"2.0","id":1}

The image builds, the runtime is the LTS line, and the server completes a real
MCP stdio handshake — not just "the build did not error".

Closes #72

🤖 Generated with Claude Code

https://claude.ai/code/session_01JKAExynd9zoKwt6rYA66EA

Dependabot PR #72 proposed node:22-alpine -> node:25-alpine. Node 25 is a
Current (odd-numbered) release that reached END OF LIFE on 2026-06-01, per
nodejs/Release schedule.json — so that bump would have pinned the published
container to a runtime receiving no further security patches, five days short
of three months after EOL. CI was green because the workflows test the packed
npm artifact on Node 18/20/22/24 and never build the Dockerfile.

Bump to node:24-alpine instead (Krypton, Active LTS, maintenance 2026-10-20,
end 2028-04-30) and tell Dependabot to stop proposing Node majors so the next
one is a deliberate move to v26 when it becomes Active LTS on 2026-10-28.
Digest-level minor/patch refreshes on the pinned major still come through.

Verified locally on 2026-08-22:
  docker build ... -> success
  docker run --entrypoint node -> v24.19.0
  MCP stdio initialize -> serverInfo {"name":"oilpriceapi","version":"3.2.3"}

Closes #72

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKAExynd9zoKwt6rYA66EA
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 568a1e2d-1b4b-469b-873a-493a41448700


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@karlwaldman

Copy link
Copy Markdown
Member Author

The two red checks are pre-existing on main and unrelated to this change — verified, not assumed.

Reproduced on unmodified origin/main (3d80602, this PR's merge base) in a detached worktree:

$ git worktree add --detach ../mcp-server-clean origin/main
$ npm ci && npm run build      # build OK
$ npm run smoke:product-facts:live
Error: canonical product-facts endpoint was unavailable after 3 MCP attempts:
  Canonical product-facts response failed contract validation.
  Serving the checksum-verified package contract reviewed 2026-08-11.

Byte-identical to the CI failure. Structurally it could not have been this PR anyway: Public product-facts compatibility smoke runs npm run smoke:product-facts:live, a network call to api.oilpriceapi.com/product-facts.json, and this PR touches only the Dockerfile base image and .github/dependabot.yml.

Root cause — api#6641, reaching its third and fourth consumer

The live endpoint declares schemaVersion: "1.0.0" while carrying an offer field v1 does not define:

$ curl -s https://api.oilpriceapi.com/product-facts.json
  schemaVersion: 1.0.0
  offer keys: [creditCardRequiredForTrial, freeRequestsPerMonth, freeRequestsWindow,
               pricingUrl, qualification, trialDays, trialRequests, trialScope]
                                          ^^^^^^^^^^^^^^^^^^^^ not in v1

$ curl -so/dev/null -w "%{http_code}" https://api.oilpriceapi.com/schemas/product-facts-v2.schema.json
404

Every exact-match consumer breaks on it. Known casualties now:

  1. oilpriceapi-docs sync-product-facts.mjs — red on every scheduled run since 2026-08-11 (docs#134); still red on today's 11:01Z run.
  2. this repo, Unit tests + buildsmoke:docker — "Container stdio did not return the live reviewed keyless product-facts contract."
  3. this repo, Public product-facts compatibility smoke.

api#6641 (typed product facts v2) is the fix; it is CLEAN with 15/15 checks green and awaiting the Friday ≥21:00 UTC elevated window. These checks go green when v2 deploys, not before — merging #6641 alone is not enough, since /schemas/product-facts-v2.schema.json 404s until it ships.

What this PR was verified against

The Node 24 change itself was proven locally, independently of the above:

$ docker build ... -t opa-mcp-node24-test:local .            → success
$ docker run --rm --entrypoint node ... --version            → v24.19.0
$ printf <initialize> | docker run --rm -i ...
{"result":{"protocolVersion":"2024-11-05","serverInfo":{"name":"oilpriceapi","version":"3.2.3"}},...}

The container builds and completes a real MCP stdio handshake on Node 24.

Recommendation: do not merge this on a green board — the board cannot go green until api#6641 deploys. Merge on the evidence above, or hold it behind #6641.

@karlwaldman
karlwaldman merged commit 25eab9d into main Aug 22, 2026
6 of 8 checks passed
@karlwaldman
karlwaldman deleted the chore/dockerfile-node-24-lts branch August 22, 2026 16:39
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