From c0ce3524b6b826f89704843cbb785c8f66a55ba5 Mon Sep 17 00:00:00 2001 From: kert Date: Tue, 27 Oct 2026 11:04:28 -0400 Subject: [PATCH] fix(images): trixie bases, locked syncs, no system pip; mc sidecar runs RustFS's rc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Base images - api, llm, docs(extract), notebooks(wheel): uv:python3.13-bookworm-slim -> uv:0.13.2-python3.13-trixie-slim. Debian 12 left regular security support in June 2026; a pinned uv tag makes base changes a reviewed diff Renovate can bump. notebooks copies /uv from the same tag instead of uv:latest. - api, llm: `uv sync --locked` — a stale lock now fails the build instead of silently re-resolving to packages pkg-supply-chain never scanned. - api, llm: uninstall the base image's system pip. Nothing runs it (uv owns the venv), and its vendored certifi/urllib3/msgpack/setuptools were the image's only language-level findings. - notebooks: the workspace resolves at build time with no committed lock, so it gets the same 7-day cooldown via ENV UV_EXCLUDE_NEWER (ENV, not a prefix — the recorded span must match at `uv run` time). - docs: pnpm 10.12.1 -> 10.34.7 to match packageManager. trivy HIGH/CRITICAL, deployed image -> this build: api 11 crit / 94 high -> 0 / 48 llm 9 / 129 -> 1 / 70 docs 0 / 38 -> 0 / 0 mc 2 / 52 -> 0 / 0 What's left is Debian `affected` with no fix released (libxml2 is the llm critical); the weekly Harden --pull rebuild picks fixes up as they land. mc sidecar MinIO archived the open-source client: quay.io/minio/mc answers 401, dl.min.io 410 Gone, and there are no more security fixes. The service keeps its name but ships rustfs/rc v0.1.36 on alpine:3.24 — same alias grammar (RC_HOST_local=http://key:secret@rustfs:9000), same admin verbs (`docker exec mc rc admin policy create local/ `), same hardening (uid 10002, read-only root, no caps). Verified against the live RustFS: `rc ls local/` lists all six buckets, `rc admin user list` reaches the admin API. Config dir moves to a tmpfs at /home/mc/.config/rc. Refs #1365 --- compose.yml | 5 +++-- infra/images/api.Dockerfile | 9 +++++++-- infra/images/docs.Dockerfile | 4 ++-- infra/images/llm.Dockerfile | 9 +++++++-- infra/images/mc.Dockerfile | 22 +++++++++++++--------- infra/images/notebooks.Dockerfile | 12 +++++++++--- 6 files changed, 41 insertions(+), 20 deletions(-) diff --git a/compose.yml b/compose.yml index b5ca748..3f67731 100644 --- a/compose.yml +++ b/compose.yml @@ -121,11 +121,12 @@ services: networks: - storage environment: - - MC_HOST_local=http://${RUSTFS_ACCESS_KEY}:${RUSTFS_SECRET_KEY}@rustfs:9000 + - RC_HOST_local=http://${RUSTFS_ACCESS_KEY}:${RUSTFS_SECRET_KEY}@rustfs:9000 + - RC_CONFIG_DIR=/home/mc/.config/rc user: "10002:10002" read_only: true tmpfs: - - /home/mc/.mc:uid=10002,gid=10002 + - /home/mc/.config/rc:uid=10002,gid=10002 security_opt: - no-new-privileges:true cap_drop: diff --git a/infra/images/api.Dockerfile b/infra/images/api.Dockerfile index 1336063..298db90 100644 --- a/infra/images/api.Dockerfile +++ b/infra/images/api.Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim +FROM ghcr.io/astral-sh/uv:0.13.2-python3.13-trixie-slim WORKDIR /app @@ -11,6 +11,9 @@ ARG PYPI_INDEX_URL="" # healthcheck timeout, so Docker marks the container unhealthy even # though /health responds in milliseconds.) RUN apt-get update && apt-get upgrade -y && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/* +# uv manages the venv; the base image's system pip is never used, and its +# vendored certifi/urllib3/msgpack/setuptools copies lag and get flagged. +RUN python3 -m pip uninstall -y -q pip # Copy project files for install COPY pyproject.toml uv.lock README.md ./ @@ -26,7 +29,9 @@ ENV UV_PYTHON_PREFERENCE=only-system \ UV_LINK_MODE=copy \ UV_PROJECT_ENVIRONMENT=.venv \ UV_INDEX_URL=${PYPI_INDEX_URL} -RUN uv sync --no-dev --extra cli --extra perf && uv pip install -e . +# --locked: a stale uv.lock fails the build instead of silently re-resolving +# to packages nobody scanned (pkg-supply-chain scans uv.lock). +RUN uv sync --locked --no-dev --extra cli --extra perf && uv pip install -e . # Config COPY stack.toml ./ diff --git a/infra/images/docs.Dockerfile b/infra/images/docs.Dockerfile index 490ca69..5887942 100644 --- a/infra/images/docs.Dockerfile +++ b/infra/images/docs.Dockerfile @@ -1,5 +1,5 @@ # Stage 1: Extract docs from Python source + export bib library -FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS extract +FROM ghcr.io/astral-sh/uv:0.13.2-python3.13-trixie-slim AS extract WORKDIR /build @@ -21,7 +21,7 @@ RUN uv run --with griffe python docs/scripts/extract_docs.py # Stage 2: Build Docusaurus static site FROM node:22-slim AS build -RUN corepack enable && corepack prepare pnpm@10.12.1 --activate +RUN corepack enable && corepack prepare pnpm@10.34.7 --activate WORKDIR /docs diff --git a/infra/images/llm.Dockerfile b/infra/images/llm.Dockerfile index 81c1b26..814a4b7 100644 --- a/infra/images/llm.Dockerfile +++ b/infra/images/llm.Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim +FROM ghcr.io/astral-sh/uv:0.13.2-python3.13-trixie-slim WORKDIR /app @@ -8,6 +8,9 @@ ARG PYPI_INDEX_URL="" # Patch base image CVEs + install curl for the healthcheck. RUN apt-get update && apt-get upgrade -y && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/* +# uv manages the venv; the base image's system pip is never used, and its +# vendored certifi/urllib3/msgpack/setuptools copies lag and get flagged. +RUN python3 -m pip uninstall -y -q pip # Word → PDF for the document viewer (llm.convert): headless Writer plus # metric-compatible fonts so Calibri/Cambria/Times/Arial letters paginate @@ -25,7 +28,9 @@ ENV UV_PYTHON_PREFERENCE=only-system \ UV_LINK_MODE=copy \ UV_PROJECT_ENVIRONMENT=.venv \ UV_INDEX_URL=${PYPI_INDEX_URL} -RUN uv sync --no-dev --extra llm --extra perf && uv pip install -e . +# --locked: a stale uv.lock fails the build instead of silently re-resolving +# to packages nobody scanned (pkg-supply-chain scans uv.lock). +RUN uv sync --locked --no-dev --extra llm --extra perf && uv pip install -e . # Config (conf reads stack.toml by walking up from CWD) COPY stack.toml ./ diff --git a/infra/images/mc.Dockerfile b/infra/images/mc.Dockerfile index 78e7d37..9900b0f 100644 --- a/infra/images/mc.Dockerfile +++ b/infra/images/mc.Dockerfile @@ -1,13 +1,17 @@ # syntax=docker/dockerfile:1 -# MinIO Client (mc) sidecar — least-privilege admin helper for RustFS. -# The image moved off Docker Hub (docker.io/minio/mc now 404s — pull access -# denied) to quay.io; pinned to a release tag so a base-image change is a -# reviewed diff, not a silent CI break. +# Object-store admin sidecar for RustFS — least-privilege IAM/bucket helper. +# The service keeps its `mc` name, but the binary is RustFS's own `rc` +# (github.com/rustfs/cli): MinIO archived the open-source mc — no security +# updates, quay.io/minio/mc now 401s and dl.min.io answers 410 Gone. rc speaks +# the same alias grammar (`RC_HOST_local=http://key:secret@host:port`) and +# admin verbs: `docker exec mc rc admin policy create local/ `. +# Pinned tags so a base-image change is a reviewed diff (Renovate bumps both). # Runs as non-root, read-only filesystem, no capabilities. -FROM quay.io/minio/mc:RELEASE.2025-08-13T08-35-41Z AS mc +FROM rustfs/rc:v0.1.36 AS rc -FROM alpine:3 -RUN addgroup -g 10002 -S mc && adduser -u 10002 -S mc -G mc -COPY --from=mc /usr/bin/mc /usr/bin/mc +FROM alpine:3.24 +RUN apk upgrade --no-cache \ + && addgroup -g 10002 -S mc && adduser -u 10002 -S mc -G mc +COPY --from=rc /usr/bin/rc /usr/bin/rc USER mc:mc -ENTRYPOINT ["mc"] +ENTRYPOINT ["rc"] diff --git a/infra/images/notebooks.Dockerfile b/infra/images/notebooks.Dockerfile index 71993f6..9ecae94 100644 --- a/infra/images/notebooks.Dockerfile +++ b/infra/images/notebooks.Dockerfile @@ -61,7 +61,7 @@ RUN rm -rf marimo/_static marimo/_lsp \ # ---- stage 2: wheel --------------------------------------------------------- -FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS wheel +FROM ghcr.io/astral-sh/uv:0.13.2-python3.13-trixie-slim AS wheel WORKDIR /src COPY --from=fe /src/ /src/ RUN uv build --wheel @@ -92,14 +92,20 @@ RUN groupmod -n ${USERNAME} ubuntu \ && usermod -l ${USERNAME} -d /home/${USERNAME} -m -s /bin/bash ubuntu \ && chown -R ${USER_UID}:${USER_GID} /home/${USERNAME} -COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv -COPY --from=ghcr.io/astral-sh/uv:latest /uvx /usr/local/bin/uvx +COPY --from=ghcr.io/astral-sh/uv:0.13.2 /uv /usr/local/bin/uv +COPY --from=ghcr.io/astral-sh/uv:0.13.2 /uvx /usr/local/bin/uvx WORKDIR /home/${USERNAME} # Bring in the fhirworx marimo wheel from the wheel stage. COPY --from=wheel /src/dist/ /tmp/marimo-wheel/ +# This workspace resolves at build time (no committed lock), so give it the +# same 7-day release cooldown as pyproject.toml. ENV, not a one-shot prefix: +# the workspace lock records the span, and a runtime `uv run` without it +# would call the lock stale and re-resolve at container start. +ENV UV_EXCLUDE_NEWER="7 days" + # Install python + init workspace venv. Use the local wheel for marimo so # the fhirworx frontend ships in the image; no upstream PyPI fetch for # marimo itself.