Part of #6
Question
Does the Panel actually build and run on gcr.io/distroless/nodejs24, and what does it cost?
The decision to go distroless is made; this ticket is the evidence that it is achievable, not a re-litigation. Build a throwaway Dockerfile and find out:
- Does
better-sqlite3 load? It is compiled in the build stage against glibc; distroless is glibc, so it should — verify rather than assume, including that the prebuilt/node:24-bookworm-compiled .node binary resolves at runtime.
- The current image runs
CMD ["node", "bin/panel.mjs"]. Distroless nodejs images have node as the entrypoint, so CMD becomes the script path. Confirm the working invocation.
HEALTHCHECK currently shells out via CMD node -e "…". With no shell, this needs CMD ["node", "-e", …] exec form, or dropping the in-image healthcheck in favour of a compose-level one. Decide which.
- The image currently does
RUN mkdir -p /data && chown node:node /data and USER node. Distroless has no RUN capability at the runtime stage — the directory and its ownership must be staged in the build image and copied. Work out how, and which distroless tag (:nonroot vs default) that implies.
- Measure the CVE delta — before and after, same scanner, so the 74 has a number to be compared against.
- Note anything lost: no shell means no
docker exec sh for debugging. Say how an operator is expected to debug the container instead, since that goes in the docs.
Deliverable: a working prototype Dockerfile linked from this issue, the measured CVE delta, and a short list of what the real implementation must not forget.
Part of #6
Question
Does the Panel actually build and run on
gcr.io/distroless/nodejs24, and what does it cost?The decision to go distroless is made; this ticket is the evidence that it is achievable, not a re-litigation. Build a throwaway Dockerfile and find out:
better-sqlite3load? It is compiled in the build stage against glibc; distroless is glibc, so it should — verify rather than assume, including that the prebuilt/node:24-bookworm-compiled.nodebinary resolves at runtime.CMD ["node", "bin/panel.mjs"]. Distrolessnodejsimages havenodeas the entrypoint, soCMDbecomes the script path. Confirm the working invocation.HEALTHCHECKcurrently shells out viaCMD node -e "…". With no shell, this needsCMD ["node", "-e", …]exec form, or dropping the in-image healthcheck in favour of a compose-level one. Decide which.RUN mkdir -p /data && chown node:node /dataandUSER node. Distroless has noRUNcapability at the runtime stage — the directory and its ownership must be staged in the build image and copied. Work out how, and which distroless tag (:nonrootvs default) that implies.docker exec shfor debugging. Say how an operator is expected to debug the container instead, since that goes in the docs.Deliverable: a working prototype Dockerfile linked from this issue, the measured CVE delta, and a short list of what the real implementation must not forget.