distribution/e2e-clients/Containerfile
# holger-e2e-clients: the build systems of Holger's end-to-end gate (Holger v2.0 H6,
# `cargo xtask e2e`). The gate runs IN this image with `--network none`: the fake
# internet, the upstream, the USB directory, the downstream and these clients, and no
# route out. Only this image's build reaches the network (Debian and PyPI, once).
#
# pip + python3 modern Python (PEP 503/691, PEP 658/714)
# uv the other Python client
# cargo a crate from a sparse registry (Debian's cargo)
# mvn + JDK 21 a Maven build; its plugins are seeded into /opt/m2 (the tail
# repository, `-Dmaven.repo.local.tail=/opt/m2`), so the build fetches
# only its dependency, from the downstream
# go a module from a GOPROXY
# skopeo an OCI image copy (no daemon)
# podman a real container runtime's pull (RA1-10): vfs storage under the test's
# own directory, one uid mapped (the demo image's files are root's)
# cc the connect trap the gate preloads into the downstream
# clamd ClamAV, the gate's sidecar: ONLY the pinned signature set in clamav/
# (no freshclam, no network); the YARA rules in yara/ are the gate's
# pinned rules (holger's built-in YARA engine runs them)
#
# PINNED (RA1-9): the image's tag is the hash of this context, so this context says the
# whole image: the base by its index digest (debian:trixie, 13.7, 2026-10-20), the archive a
# dated snapshot (deb.debian.org moves under a tag), and every package by version. A new
# version is a change here, and so a new tag.
FROM docker.io/library/debian:trixie@sha256:4c25275446ca371766b8b093c696782eabce06263fccacb8d5d813b3dc44b308
RUN printf '%s\n' 'Types: deb' 'URIs: http://snapshot.debian.org/archive/debian/20261026T100000Z' 'Suites: trixie trixie-updates' \
'Components: main' 'Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp' '' \
'Types: deb' 'URIs: http://snapshot.debian.org/archive/debian-security/20261026T100000Z' 'Suites: trixie-security' \
'Components: main' 'Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp' > /etc/apt/sources.list.d/debian.sources \
&& apt-get -o Acquire::Check-Valid-Until=false update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates=20250419+deb13u1 python3=3.13.5-1 python3-pip=25.1.1+dfsg-1 python3-venv=3.13.5-1 \
gcc=4:14.2.0-1 libc6-dev=2.41-12+deb13u4 maven=3.9.9-1 openjdk-21-jdk-headless=21.0.12.1+1-1~deb13u1 \
golang-go=2:1.24~2 skopeo=1.18.0+ds1-1+b5 cargo=1.85.1+dfsg1-1+deb13u1 podman=5.4.2+ds1-2+b2 \
clamav-daemon=1.4.3+dfsg-1 clamav-base=1.4.3+dfsg-1 clamav-freshclam=1.4.3+dfsg-1 libclamav12=1.4.3+dfsg-1 \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir --break-system-packages uv==0.8.22
COPY seed /opt/seed
RUN cd /opt/seed && mvn -B -q -Dmaven.repo.local=/opt/m2 package && rm -rf /opt/seed/target \
&& chmod -R a+rX /opt/m2
COPY clamav/holger-e2e.ndb /opt/holger-e2e/clamav/holger-e2e.ndb
COPY clamav/clamd.conf /etc/holger-e2e/clamd.conf
COPY yara /opt/holger-e2e/yara
RUN rm -rf /var/lib/clamav/* && chmod -R a+rX /opt/holger-e2e /etc/holger-e2e
ENV HOME=/tmp GOTOOLCHAIN=local GOFLAGS=-mod=mod