Install Node.js from Debian's own repo, drop NodeSource dependency
Build and push server image / test (push) Successful in 30s
Build and push server image / build-and-push (push) Successful in 2m34s
Build and push server image / deploy (push) Successful in 53s

deb.nodesource.com started intermittently 403ing today on both its
setup_*.x scripts and its GPG key (confirmed directly, not just via CI --
some setup_NN.x paths 403, others 200, no consistent pattern), and the
curl-piped-into-bash install pattern silently swallowed that failure
instead of breaking the build loudly: curl -f exits non-zero on a 403,
but bash then runs on empty stdin and exits 0, so the RUN kept going
into a broken fallback (Debian's own split nodejs package with no
bundled npm) rather than stopping.

This base image now tracks Debian trixie, whose own nodejs package
(20.19.2) is inside jsdom 29's engines range and clears express/
resvg-js's much lower floors -- the version gap that originally required
routing through NodeSource is gone, so this drops that whole external
dependency (and the curl/gnupg install-then-purge dance) rather than
just swapping to a different NodeSource script.
This commit is contained in:
2026-07-27 20:40:30 +00:00
parent b15747a604
commit 4e8c6e534b
+29 -25
View File
@@ -2,34 +2,38 @@ FROM python:3.12-slim
WORKDIR /app WORKDIR /app
# tzdata/fonts in their own layer, kept separate from the much larger # tzdata/fonts/Node.js all from Debian's own repo in one layer -- no
# Node.js/npm layers below -- see those layers' own comments for why # external curl/gnupg dance needed (see below for why that changed).
# they're split up the way they are. tzdata: python:3.12-slim doesn't # tzdata: python:3.12-slim doesn't include it by default, so the
# include it by default, so the zoneinfo database backing the web UI's # zoneinfo database backing the web UI's "Timezone" setting (used by
# "Timezone" setting (used by "Quiet hours") would have no named zones # "Quiet hours") would have no named zones to resolve without this --
# to resolve without this -- ZoneInfo() would raise for anything other # ZoneInfo() would raise for anything other than "UTC".
# than "UTC". fontconfig/fonts-dejavu-core: whiteboard mode's # fontconfig/fonts-dejavu-core: whiteboard mode's render-service/ (own
# render-service/ (own README there) needs something to render # README there) needs something to render whiteboard text with.
# whiteboard text with. #
RUN apt-get update && apt-get install -y --no-install-recommends \
tzdata fontconfig fonts-dejavu-core \
&& rm -rf /var/lib/apt/lists/*
# Node.js: whiteboard frame mode's render-service/ runs as a second # Node.js: whiteboard frame mode's render-service/ runs as a second
# process in this same container rather than a separate compose service # process in this same container rather than a separate compose service
# -- it's a lightweight, stateless, localhost-only sidecar with nothing # -- it's a lightweight, stateless, localhost-only sidecar with nothing
# worth independently scaling or restarting. NodeSource's setup script is # worth independently scaling or restarting. Used to be installed via
# used instead of Debian bookworm's own apt Node package, which is both # NodeSource's setup script (Debian's own nodejs package was too old for
# older than jsdom's minimum (20.19+) and inconsistently available. # jsdom's minimum back when this base image tracked Debian bookworm) --
# curl/gnupg are only needed to add and fetch NodeSource's repo -- purged # switched to Debian's own `nodejs`/`npm` packages after NodeSource's
# again in this same RUN (not a later one; Docker layers are immutable, # deb.nodesource.com started intermittently 403ing on both its setup_*.x
# so removing them in a *different* instruction wouldn't shrink this # scripts *and* its GPG key (a live NodeSource-side S3/CDN issue,
# one's actual pushed size) so their bytes don't end up in the image at # confirmed 2026-07-27 by hitting deb.nodesource.com directly -- some
# all, only nodejs's. # setup_NN.x paths 403, others 200, no consistent pattern, so no
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates gnupg \ # NodeSource-hosted install path could be trusted not to silently break
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ # again). This base image now tracks Debian trixie, whose own `nodejs`
&& apt-get install -y --no-install-recommends nodejs \ # package is 20.19.2 -- inside jsdom 29's stated engines range
&& apt-get purge -y --auto-remove curl gnupg \ # (`^20.19.0 || ^22.13.0 || >=24.0.0`) and well above express/resvg-js's
# much lower floors -- so there's no longer a version gap to route
# around NodeSource for. One less external dependency, and no more
# curl-piped-into-bash (that pattern is also what let the NodeSource
# failure go undetected here in the first place: `curl -f ... | bash -`
# on a 403 hands bash an empty, "successful" script instead of failing
# the RUN outright).
RUN apt-get update && apt-get install -y --no-install-recommends \
tzdata fontconfig fonts-dejavu-core nodejs npm \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
COPY requirements.txt . COPY requirements.txt .