fix(images): trixie bases, locked syncs, no system pip; mc sidecar runs RustFS's rc

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/ <name> <file>`), 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
This commit is contained in:
kert
2026-10-27 11:04:28 -04:00
parent ab118d9f13
commit c0ce3524b6
6 changed files with 41 additions and 20 deletions

View File

@@ -121,11 +121,12 @@ services:
networks: networks:
- storage - storage
environment: 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" user: "10002:10002"
read_only: true read_only: true
tmpfs: tmpfs:
- /home/mc/.mc:uid=10002,gid=10002 - /home/mc/.config/rc:uid=10002,gid=10002
security_opt: security_opt:
- no-new-privileges:true - no-new-privileges:true
cap_drop: cap_drop:

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1 # 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 WORKDIR /app
@@ -11,6 +11,9 @@ ARG PYPI_INDEX_URL=""
# healthcheck timeout, so Docker marks the container unhealthy even # healthcheck timeout, so Docker marks the container unhealthy even
# though /health responds in milliseconds.) # 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/* 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 project files for install
COPY pyproject.toml uv.lock README.md ./ COPY pyproject.toml uv.lock README.md ./
@@ -26,7 +29,9 @@ ENV UV_PYTHON_PREFERENCE=only-system \
UV_LINK_MODE=copy \ UV_LINK_MODE=copy \
UV_PROJECT_ENVIRONMENT=.venv \ UV_PROJECT_ENVIRONMENT=.venv \
UV_INDEX_URL=${PYPI_INDEX_URL} 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 # Config
COPY stack.toml ./ COPY stack.toml ./

View File

@@ -1,5 +1,5 @@
# Stage 1: Extract docs from Python source + export bib library # 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 WORKDIR /build
@@ -21,7 +21,7 @@ RUN uv run --with griffe python docs/scripts/extract_docs.py
# Stage 2: Build Docusaurus static site # Stage 2: Build Docusaurus static site
FROM node:22-slim AS build 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 WORKDIR /docs

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1 # 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 WORKDIR /app
@@ -8,6 +8,9 @@ ARG PYPI_INDEX_URL=""
# Patch base image CVEs + install curl for the healthcheck. # 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/* 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 # Word → PDF for the document viewer (llm.convert): headless Writer plus
# metric-compatible fonts so Calibri/Cambria/Times/Arial letters paginate # 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_LINK_MODE=copy \
UV_PROJECT_ENVIRONMENT=.venv \ UV_PROJECT_ENVIRONMENT=.venv \
UV_INDEX_URL=${PYPI_INDEX_URL} 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) # Config (conf reads stack.toml by walking up from CWD)
COPY stack.toml ./ COPY stack.toml ./

View File

@@ -1,13 +1,17 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
# MinIO Client (mc) sidecar — least-privilege admin helper for RustFS. # Object-store admin sidecar for RustFS — least-privilege IAM/bucket helper.
# The image moved off Docker Hub (docker.io/minio/mc now 404s — pull access # The service keeps its `mc` name, but the binary is RustFS's own `rc`
# denied) to quay.io; pinned to a release tag so a base-image change is a # (github.com/rustfs/cli): MinIO archived the open-source mc — no security
# reviewed diff, not a silent CI break. # 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/ <name> <file>`.
# Pinned tags so a base-image change is a reviewed diff (Renovate bumps both).
# Runs as non-root, read-only filesystem, no capabilities. # 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 FROM alpine:3.24
RUN addgroup -g 10002 -S mc && adduser -u 10002 -S mc -G mc RUN apk upgrade --no-cache \
COPY --from=mc /usr/bin/mc /usr/bin/mc && addgroup -g 10002 -S mc && adduser -u 10002 -S mc -G mc
COPY --from=rc /usr/bin/rc /usr/bin/rc
USER mc:mc USER mc:mc
ENTRYPOINT ["mc"] ENTRYPOINT ["rc"]

View File

@@ -61,7 +61,7 @@ RUN rm -rf marimo/_static marimo/_lsp \
# ---- stage 2: wheel --------------------------------------------------------- # ---- 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 WORKDIR /src
COPY --from=fe /src/ /src/ COPY --from=fe /src/ /src/
RUN uv build --wheel RUN uv build --wheel
@@ -92,14 +92,20 @@ RUN groupmod -n ${USERNAME} ubuntu \
&& usermod -l ${USERNAME} -d /home/${USERNAME} -m -s /bin/bash ubuntu \ && usermod -l ${USERNAME} -d /home/${USERNAME} -m -s /bin/bash ubuntu \
&& chown -R ${USER_UID}:${USER_GID} /home/${USERNAME} && 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:0.13.2 /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 /uvx /usr/local/bin/uvx
WORKDIR /home/${USERNAME} WORKDIR /home/${USERNAME}
# Bring in the fhirworx marimo wheel from the wheel stage. # Bring in the fhirworx marimo wheel from the wheel stage.
COPY --from=wheel /src/dist/ /tmp/marimo-wheel/ 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 # Install python + init workspace venv. Use the local wheel for marimo so
# the fhirworx frontend ships in the image; no upstream PyPI fetch for # the fhirworx frontend ships in the image; no upstream PyPI fetch for
# marimo itself. # marimo itself.