runtime image: Debian 13 base + headless-Chromium shared libs (v4)
Nightly Build / build (push) Successful in 7m49s

python3 >= 3.12 is increasingly a hard floor for PyPI packages a connector
pulls (mcp-server-linkedin declares `requires-python >=3.12,<3.15`), and
`install::ensure_installed` runs the deps install as a plain `python3 -m pip`,
so the system interpreter is what every python connector builds against.
Trixie ships 3.13; it also moves node 18 -> 20 and tesseract 5.3 -> 5.5.

Adds the shared libraries a headless Chromium links against, for connectors
driving a real browser. Libs only — the browser binary is not baked in, the
connector downloads its own pinned build under its connector dir. That split
is the point: a pip/npm install can fetch a binary but cannot supply system
libs, so these are the genuinely non-self-recoverable half. The list is
patchright's own nativeDeps table for debian13; the `t64` suffixes are Debian
13's 64-bit time_t transition and are not optional.

IMAGE_TAG -> v4 so existing containers are recreated, not just new ones.
This commit is contained in:
2026-08-07 13:18:04 +01:00
parent 548871fc72
commit fb6f8ef195
2 changed files with 45 additions and 4 deletions
+40 -1
View File
@@ -16,7 +16,13 @@
# (~270 MB, only for `pip install` of a package with no wheel) and `pandoc` # (~270 MB, only for `pip install` of a package with no wheel) and `pandoc`
# (~216 MB, niche) are big *and* self-recoverable, so they stay on demand. # (~216 MB, niche) are big *and* self-recoverable, so they stay on demand.
FROM debian:bookworm-slim # Trixie (Debian 13), not bookworm, for python3 >= 3.12: connectors that pull a
# modern PyPI package are increasingly gated on it (mcp-server-linkedin declares
# `requires-python >=3.12,<3.15`), and `install::ensure_installed` runs the deps
# install as a plain `python3 -m pip` — so the system interpreter is the floor
# every python connector builds against. Trixie ships 3.13. Note this also moves
# node 18 -> 20 and tesseract 5.3 -> 5.5.
FROM debian:trixie-slim
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
@@ -57,6 +63,39 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
tesseract-ocr \ tesseract-ocr \
tesseract-ocr-ita \ tesseract-ocr-ita \
tesseract-ocr-fra \ tesseract-ocr-fra \
# Shared libraries a headless Chromium links against, for connectors that
# drive a real browser (the LinkedIn connector via patchright). Only the
# libs: the browser *binary* is NOT baked in — the connector downloads its
# own pinned build into `PLAYWRIGHT_BROWSERS_PATH` under its connector dir,
# where it is durable across container recreates. That split is deliberate:
# a pip/npm install can fetch a binary, but it cannot supply system libs, so
# these are the part that is genuinely not self-recoverable. Cheap here —
# most are already pulled in transitively by ffmpeg/imagemagick/tesseract.
# The list is patchright's own `nativeDeps` table for debian13; the `t64`
# suffixes are Debian 13's 64-bit time_t transition and are NOT optional.
libasound2t64 \
libatk-bridge2.0-0t64 \
libatk1.0-0t64 \
libatspi2.0-0t64 \
libcairo2 \
libcups2t64 \
libdbus-1-3 \
libdrm2 \
libgbm1 \
libglib2.0-0t64 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libx11-6 \
libxcb1 \
libxcomposite1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxkbcommon0 \
libxrandr2 \
fonts-liberation \
fonts-noto-color-emoji \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# The container runs as the host process's uid:gid (blueprint §6 UID coherence), so # The container runs as the host process's uid:gid (blueprint §6 UID coherence), so
+5 -3
View File
@@ -37,9 +37,11 @@ use crate::tools::fs as fs_tools;
/// suffix is the image cache-buster: [`ContainerManager::ensure_image`] rebuilds only /// suffix is the image cache-buster: [`ContainerManager::ensure_image`] rebuilds only
/// when the tag is absent, so **bump it whenever the [`Dockerfile`] changes** (`v2` /// when the tag is absent, so **bump it whenever the [`Dockerfile`] changes** (`v2`
/// added `sudo` + a NOPASSWD sudoers for the non-root container user; `v3` added /// added `sudo` + a NOPASSWD sudoers for the non-root container user; `v3` added
/// `unzip` + `ffmpeg`). Old tags linger as orphaned images (harmless), but existing /// `unzip` + `ffmpeg`; `v4` moved the base to Debian 13 for python3 >= 3.12 and
/// containers still *run* one — which is why [`reusable`] also compares the image. /// added the headless-Chromium shared libs). Old tags linger as orphaned images
const IMAGE_TAG: &str = "skald-runtime:v3"; /// (harmless), but existing containers still *run* one — which is why [`reusable`]
/// also compares the image.
const IMAGE_TAG: &str = "skald-runtime:v4";
/// The embedded Dockerfile — the source of truth, so the image can be built with /// The embedded Dockerfile — the source of truth, so the image can be built with
/// no files shipped alongside the binary (binary-first). /// no files shipped alongside the binary (binary-first).