Backward compatible; existing modes unchanged for existing callers.
- apt: also rewrites deb.debian.org/debian, deb.debian.org/debian-security and
security.debian.org to <cache>/debian and <cache>/debian-security; the
listing no longer fails under pipefail when /etc/apt/sources.list is absent
(Debian 13 images).
- rpm: rewrites rpm.nodesource.com repos to <cache>/nodesource (gpgcheck=1;
NodeSource does not sign repomd).
- new `nodesource MAJOR`: writes the nodesource-nodejs repo itself with the
committed signing key (replaces curl setup_N.x | bash).
- new `go-env`: prints GOPROXY=<cache>/goproxy|https://proxy.golang.org|direct
plus SSL_CERT_FILE for the RUN; go.sum + sum.golang.org still verify.
- release-install: EL9 or EL10 picked from rpm %rhel; adds RPM-GPG-KEY-EPEL-9.
- PKG_CACHE is regex-validated.
Tested through the cache on a throwaway runner CT (pve vmbr2): EL9+EPEL9,
NodeSource 22 on EL10, Debian trixie apt, golang:1.25 apt + go-env; restore
left no cache reference in each case.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shell-Checks' structural scan (scripts/tests/lsphp-info-probe.test.sh)
flagged two `cmd | while read` loops in pkg-cache-repos.sh restore.
Read the lists with mapfile from a process substitution instead, so
there is no pipeline. The test now passes locally (36/0), shellcheck is
clean, and the restore tests (new cache-referencing file removed,
leftover reference -> FATAL) behave as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Security review follow-up for the opt-in PKG_CACHE path:
- PKG_CACHE must be https:// (http is refused). The cache's certificate
comes from a name-constrained internal CA (keys/pkg-cache/ca.crt, valid
only for 192.168.1.40 / pkg-cache.*). The CA is trusted only by the
rewritten repos (dnf sslcacert bundle, apt per-host CaInfo) and only
for the duration of the RUN.
- epel-release / remi-release are no longer installed straight from a
URL. release-install downloads them over HTTPS, checks the package name,
imports the signing keys committed in keys/pkg-cache/ and requires
`rpm -K` "signatures OK", then installs with localpkg_gpgcheck=1. This
applies with and without the cache.
- Rewritten repos get gpgcheck=1. Remi and AlmaLinux also get
repo_gpgcheck=1, since both sign repomd.xml. EPEL does not publish a
repomd signature, so it relies on end-to-end HTTPS.
- restore also deletes files it created and any new repo/apt file that
still references the cache, then fails the build if a reference remains
under /etc/yum.repos.d, /etc/dnf or /etc/apt.
- docs: trust model, replay risk, proposed openssl/httpd/ImageMagick
minimum-version gates, TLS registry mirror (BuildKit ca= / dockerd
certs.d, no insecure-registries).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds scripts/pkg-cache-repos.sh and wires it into Dockerfile,
Dockerfile.fpm, Dockerfile.shared-httpd and Dockerfile.shared-ols. With
--build-arg PKG_CACHE=http://192.168.1.40 (CT130 pkg-cache), dnf/apt go
through the LAN cache. That cache fetches from the Remi/EPEL/AlmaLinux/
Ubuntu/LiteSpeed origins over HTTPS, with fallback tiers and
stale-on-error. Without the arg the script is a no-op and builds are
unchanged.
- rpm: each baseurl becomes "<cache>/<prefix>/... <origin>/...", so dnf
fails over to the origin if the cache dies mid-build
- every RUN restores the original repo files before it ends, so no
shipped layer carries the LAN address
- EPEL/Remi release RPMs come from the cache when it is set
- the php.net version gates are untouched
Dockerfile.litespeed/.lsphp are not wired yet (see docs/pkg-cache.md).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>