diff --git a/server/Dockerfile b/server/Dockerfile index 581ca9a..20b91eb 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -2,31 +2,58 @@ FROM python:3.12-slim WORKDIR /app -# tzdata: python:3.12-slim doesn't include it by default, so the zoneinfo -# database backing the web UI's "Timezone" setting (used by "Quiet hours") -# would have no named zones to resolve without this -- ZoneInfo() would -# raise for anything other than "UTC". -# -# Node.js + fonts: whiteboard frame mode's render-service/ (own README -# there) runs as a second process in this same container rather than a -# separate compose service -- it's a lightweight, stateless, localhost- -# only sidecar with nothing worth independently scaling or restarting. -# NodeSource's setup script is used instead of Debian bookworm's own -# apt Node package, which is both older than jsdom's minimum (20.19+) -# and inconsistently available. fonts-dejavu-core gives the sidecar's -# SVG rasterizer something to render whiteboard text with. +# tzdata/fonts in their own layer, kept separate from the much larger +# Node.js/npm layers below -- see those layers' own comments for why +# they're split up the way they are. tzdata: python:3.12-slim doesn't +# include it by default, so the zoneinfo database backing the web UI's +# "Timezone" setting (used by "Quiet hours") would have no named zones +# to resolve without this -- ZoneInfo() would raise for anything other +# than "UTC". fontconfig/fonts-dejavu-core: whiteboard mode's +# render-service/ (own README there) needs something to render +# whiteboard text with. RUN apt-get update && apt-get install -y --no-install-recommends \ - tzdata curl ca-certificates gnupg fontconfig fonts-dejavu-core \ + tzdata fontconfig fonts-dejavu-core \ + && rm -rf /var/lib/apt/lists/* + +# Node.js: whiteboard frame mode's render-service/ runs as a second +# process in this same container rather than a separate compose service +# -- it's a lightweight, stateless, localhost-only sidecar with nothing +# worth independently scaling or restarting. NodeSource's setup script is +# used instead of Debian bookworm's own apt Node package, which is both +# older than jsdom's minimum (20.19+) and inconsistently available. +# curl/gnupg are only needed to add and fetch NodeSource's repo -- purged +# again in this same RUN (not a later one; Docker layers are immutable, +# so removing them in a *different* instruction wouldn't shrink this +# one's actual pushed size) so their bytes don't end up in the image at +# all, only nodejs's. +RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates gnupg \ && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ + && apt-get purge -y --auto-remove curl gnupg \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -COPY render-service ./render-service -RUN cd render-service && npm install --omit=dev +# render-service/'s dependencies installed as several separate layers +# rather than one `npm install` covering all of them -- a from-scratch +# push of this image once hit Cloudflare's payload-size limit on a +# single blob/layer upload (the registry sits behind it), and splitting +# a big layer into several smaller ones is the direct fix for exactly +# that failure mode, independent of anything about the registry itself. +# --no-save: package.json already fully declares these (with the exact +# same version pins used here) as the single source of truth for what +# this service depends on -- these calls are just about *when* each one +# gets installed for layer-size reasons, not re-deciding what's needed. +COPY render-service/package.json ./render-service/package.json +WORKDIR /app/render-service +RUN npm install --omit=dev --no-save express@^5.2.1 && npm cache clean --force +RUN npm install --omit=dev --no-save jsdom@^29.1.1 && npm cache clean --force +RUN npm install --omit=dev --no-save @excalidraw/utils@0.1.3-test32 && npm cache clean --force +RUN npm install --omit=dev --no-save @resvg/resvg-js@2.6.2 && npm cache clean --force +WORKDIR /app +COPY render-service/server.js ./render-service/server.js COPY app ./app COPY start.sh . RUN chmod +x start.sh