Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit eb494b034e55ea07d47a490d1427b27d3b259f4c
parent 04dab989c7bb88216795073918d8bcb3fea0377f
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Tue,  6 Oct 2026 09:23:01 -0400

docker: the image runs Node 22 everywhere — the pinned wrangler's engines floor; one major for the build stage and every runtime

NODE_IMAGE and RUNTIME_IMAGE node:22-bookworm-slim (glibc 2.36, unchanged), the
Vulkan overlay node:22-trixie-slim, runtime-cuda NODE_MAJOR=22 on ubuntu 24.04.
Two drift tests: one Node major across all four (the native modules are built
once, against the build stage's ABI), and that major >= wrangler's engines floor
(skipped where wrangler is not installed).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
MDockerfile | 14+++++++++++---
Mcommon/publish/buildImage.test.ts | 47+++++++++++++++++++++++++++++++++++++++++++++++
Mdocker-compose.vulkan.yml | 8++++----
3 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/Dockerfile b/Dockerfile @@ -39,10 +39,18 @@ # bookworm is 2.36, trixie 2.41, ubuntu 24.04 2.39 — so building on bookworm and # running on any of them is safe, and moving NODE_IMAGE to trixie would silently # break the CUDA target. If you bump one of these, check that direction first. -ARG NODE_IMAGE=node:20-bookworm-slim +# +# NODE'S MAJOR IS THE SECOND RULE, and it must be the same everywhere: the +# native modules are compiled against the build stage's Node ABI, so every +# runtime (NODE_IMAGE, RUNTIME_IMAGE here and in docker-compose.vulkan.yml, +# NODE_MAJOR in runtime-cuda) carries the same major. 22, not 20: the wrangler +# pinned in common/package.json refuses to start on anything older (its +# engines floor), and every deploy runs it from this image. +# common/publish/buildImage.test.ts holds all four to one major and that floor. +ARG NODE_IMAGE=node:22-bookworm-slim # The runtime base, overridable per target: docker-compose.vulkan.yml builds with # trixie because the Vulkan stack needs it (see the parakeet stage below). -ARG RUNTIME_IMAGE=node:20-bookworm-slim +ARG RUNTIME_IMAGE=node:22-bookworm-slim # ubuntu24.04, not 22.04: 22.04 is glibc 2.35, OLDER than the bookworm the # workspace is built on, and the native modules would not load. ARG CUDA_DEVEL_IMAGE=nvidia/cuda:12.6.3-devel-ubuntu24.04 @@ -456,7 +464,7 @@ ENV ARCHILYZER_COMMIT=${ARCHILYZER_COMMIT} \ # --------------------------------------------------------------------------- FROM ${CUDA_RUNTIME_IMAGE} AS runtime-cuda -ARG NODE_MAJOR=20 +ARG NODE_MAJOR=22 # The same python + pipx + git-filter-repo as runtime-base (read its comments). RUN apt-get update \ && apt-get install -y --no-install-recommends \ diff --git a/common/publish/buildImage.test.ts b/common/publish/buildImage.test.ts @@ -126,3 +126,50 @@ test("every runtime target names its own yt-dlp and links the from-source wrappe assert.equal(links.length, 2); assert.ok(existsSync(path.join(REPO, "docker", "yt-dlp-from-source.sh"))); }); + +// Node's major, everywhere the image is built or run: the build stage +// (NODE_IMAGE), the default runtime (RUNTIME_IMAGE), the Vulkan overlay's +// runtime and runtime-cuda's nodesource major. The native modules are compiled +// once against the build stage's ABI, so all of them must agree. +function imageNodeMajors(): Record<string, number> { + const dockerfile = readFileSync(path.join(REPO, "Dockerfile"), "utf8"); + const vulkan = readFileSync(path.join(REPO, "docker-compose.vulkan.yml"), "utf8"); + const one = (re: RegExp, text: string, what: string) => { + const m = re.exec(text); + assert.ok(m, `${what} not found`); + return Number(m[1]); + }; + const out: Record<string, number> = { + NODE_IMAGE: one(/^ARG NODE_IMAGE=node:(\d+)-/m, dockerfile, "ARG NODE_IMAGE=node:<major>-…"), + RUNTIME_IMAGE: one(/^ARG RUNTIME_IMAGE=node:(\d+)-/m, dockerfile, "ARG RUNTIME_IMAGE=node:<major>-…"), + NODE_MAJOR: one(/^ARG NODE_MAJOR=(\d+)$/m, dockerfile, "ARG NODE_MAJOR=<major> (runtime-cuda)"), + }; + const vk = [...vulkan.matchAll(/RUNTIME_IMAGE: node:(\d+)-/g)].map((m) => Number(m[1])); + assert.ok(vk.length > 0, "docker-compose.vulkan.yml names a RUNTIME_IMAGE"); + vk.forEach((v, i) => (out[`vulkan RUNTIME_IMAGE #${i + 1}`] = v)); + return out; +} + +test("every image target runs the Node major the build stage compiled the native modules for", () => { + const majors = imageNodeMajors(); + assert.equal(new Set(Object.values(majors)).size, 1, `one Node major everywhere, found ${JSON.stringify(majors)}`); +}); + +// Every deploy runs the wrangler pinned in common's devDependencies from this +// image, and wrangler refuses to start below its engines floor (4.x: >=22). +// Skipped where wrangler is not installed. +test("the image's Node major meets the pinned wrangler's engines floor", (t) => { + const pkg = path.join(REPO, "common", "node_modules", "wrangler", "package.json"); + if (!existsSync(pkg)) { + t.skip("wrangler is not installed in common/node_modules"); + return; + } + const engines = (JSON.parse(readFileSync(pkg, "utf8")) as { engines?: { node?: string } }).engines?.node ?? ""; + const floor = /(\d+)/.exec(engines); + assert.ok(floor, `wrangler's engines.node (${JSON.stringify(engines)}) names a major`); + const major = imageNodeMajors().NODE_IMAGE; + assert.ok( + major >= Number(floor[1]), + `the image runs Node ${major}, and wrangler needs ${engines} — every deploy from the container would exit 1`, + ); +}); diff --git a/docker-compose.vulkan.yml b/docker-compose.vulkan.yml @@ -38,7 +38,7 @@ services: # The Vulkan stack needs a newer Debian than the default image runs on; # the Dockerfile explains why, and why the workspace is still BUILT on # the older one. - RUNTIME_IMAGE: node:20-trixie-slim + RUNTIME_IMAGE: node:22-trixie-slim image: archilyzer:${ARCHILYZER_TAG:-local}-vulkan devices: # The render node. This is the whole GPU passthrough — no toolkit, no @@ -59,17 +59,17 @@ services: build: target: runtime-vulkan args: - RUNTIME_IMAGE: node:20-trixie-slim + RUNTIME_IMAGE: node:22-trixie-slim image: archilyzer:${ARCHILYZER_TAG:-local}-vulkan homepage: build: target: runtime-vulkan args: - RUNTIME_IMAGE: node:20-trixie-slim + RUNTIME_IMAGE: node:22-trixie-slim image: archilyzer:${ARCHILYZER_TAG:-local}-vulkan umtool: build: target: runtime-vulkan args: - RUNTIME_IMAGE: node:20-trixie-slim + RUNTIME_IMAGE: node:22-trixie-slim image: archilyzer:${ARCHILYZER_TAG:-local}-vulkan