From fb6f8ef1950de96bb2eddd2b25b32bd470edd01d Mon Sep 17 00:00:00 2001 From: xavix-yo Date: Fri, 7 Aug 2026 13:18:04 +0100 Subject: [PATCH] runtime image: Debian 13 base + headless-Chromium shared libs (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- crates/skald-core/src/container/Dockerfile | 41 +++++++++++++++++++++- crates/skald-core/src/container/mod.rs | 8 +++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/crates/skald-core/src/container/Dockerfile b/crates/skald-core/src/container/Dockerfile index c8cfccc..f9d66fe 100644 --- a/crates/skald-core/src/container/Dockerfile +++ b/crates/skald-core/src/container/Dockerfile @@ -16,7 +16,13 @@ # (~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. -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 @@ -57,6 +63,39 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ tesseract-ocr \ tesseract-ocr-ita \ 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/* # The container runs as the host process's uid:gid (blueprint §6 UID coherence), so diff --git a/crates/skald-core/src/container/mod.rs b/crates/skald-core/src/container/mod.rs index 8fce4fa..0e9d160 100644 --- a/crates/skald-core/src/container/mod.rs +++ b/crates/skald-core/src/container/mod.rs @@ -37,9 +37,11 @@ use crate::tools::fs as fs_tools; /// suffix is the image cache-buster: [`ContainerManager::ensure_image`] rebuilds only /// 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 -/// `unzip` + `ffmpeg`). Old tags linger as orphaned images (harmless), but existing -/// containers still *run* one — which is why [`reusable`] also compares the image. -const IMAGE_TAG: &str = "skald-runtime:v3"; +/// `unzip` + `ffmpeg`; `v4` moved the base to Debian 13 for python3 >= 3.12 and +/// added the headless-Chromium shared libs). Old tags linger as orphaned images +/// (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 /// no files shipped alongside the binary (binary-first).