Zum Hauptinhalt springen

Paket-Caches

fremforge betreibt keine separaten gemeinsamen Caches für gehostete Runner mehr. Der Cache ist der eigene Dependency-Proxy deiner Organisation, in derselben EU-Region wie die Runner-VMs. Ist Runner-Pull-Through eingeschaltet (der Standard für jede Organisation, die keine eigenen Einstellungen für den Dependency-Proxy gespeichert hat), wird jeder Job beim Start auf ihn ausgerichtet (siehe Hosted runners):

DatenverkehrAuf deinen Proxy ausgerichtet überOhne Runner-Pull-Through oder beim Rückfall
npm, pnpm (über die npmrc des Jobs)die npm-Registry-Einstellungregistry.npmjs.org
pip und uvPIP_INDEX_URL, UV_DEFAULT_INDEXPyPI
Go, Maven, NuGet (jeweils, wenn in runner_pull_through_ecosystems aufgeführt; standardmäßig alle)GOPROXY, ein Maven-Mirror von Central, eine rechnerweite NuGet.Configproxy.golang.org, Maven Central, nuget.org
Trivy-Schwachstellendatenbank (wenn trivy aufgeführt ist)TRIVY_DB_REPOSITORY, TRIVY_JAVA_DB_REPOSITORYghcr.io/aquasecurity
Container-Imagesden Docker-Daemon des Jobs (siehe Container-Images)die Registry, die das Image nennt

Jeder Rückfall geht über den EU-Egress-Proxy von fremforge an die öffentliche Registry. Der Proxy wird zu Beginn jedes Jobs geprüft; ist er nicht erreichbar, nutzt der Job die öffentlichen Registrys, und der Rückfall wird protokolliert.

Der Proxy läuft in derselben OTC-Region wie die Runner-VMs (eu-de, Deutschland). Ein Cache-Miss wird über den Egress von fremforge vom Upstream geholt und für den nächsten Workflow deiner Organisation zwischengespeichert.

Warum das automatisch geschieht

Eine typische Installation von Abhängigkeiten zieht bei jedem Build Dutzende Megabyte an Paketen. Ohne Cache läuft dieser Datenverkehr jedes Mal über das NAT-Gateway und holt alles vom öffentlichen Index. Mit Cache kommen bereits zwischengespeicherte Pakete stattdessen aus Speicher in derselben Region.

Du musst nichts konfigurieren: Jedes Werkzeug beachtet seine Einstellung automatisch. yarn und bun werden nicht auf den Proxy ausgerichtet; sie installieren über den Egress-Proxy von fremforge von registry.npmjs.org.

Pro Workflow überschreiben

Zum Überschreiben (z. B. wenn du aus einer privaten Registry ziehen musst) setzt du die Variable im env deines Workflows:

jobs:
  build:
    runs-on: fremforge
    env:
      NPM_CONFIG_REGISTRY: https://npm.your-company.example/
    steps:
      - run: npm ci

env: auf Schrittebene wird ebenfalls beachtet. Deine Einstellung hat immer Vorrang vor dem Standard von fremforge.

pnpm 11 liest NPM_CONFIG_REGISTRY nicht: Setze zusätzlich PNPM_CONFIG_REGISTRY auf dieselbe URL, sonst installiert pnpm 11 weiterhin von registry.npmjs.org.

Container-Images

Ist Runner-Pull-Through eingeschaltet, zieht der Docker-Daemon des Jobs Container-Images über den Dependency-Proxy deiner Organisation, und sie werden für deine Organisation zwischengespeichert: docker pull, docker run, das FROM eines Dockerfiles sowie die Job- und services:-Container. Die Image-Namen bleiben, wie sie sind. Das gilt für ghcr.io, quay.io, mcr.microsoft.com, registry.k8s.io, public.ecr.aws und registry.access.redhat.com, für jede Organisation. Ist der Proxy nicht erreichbar oder kann er einen Pull nicht bedienen, wird das Image direkt aus der Registry gezogen. Für Images ist der Proxy ein Cache, keine Sperre. Ein docker buildx-Builder mit dem Treiber docker-container zieht direkt. Einzelheiten unter Hosted runners.

Docker-Hub-Images

Es gibt keinen gemeinsamen Docker-Hub-Mirror, und DOCKER_MIRROR_URL wird nicht mehr gesetzt. Docker Hub (docker.io) läuft wie registry.redhat.io und registry.connect.redhat.com nur mit der eigenen Zugangsberechtigung deiner Organisation über deinen Proxy. Ohne sie ist ein docker pull oder FROM eines Docker-Hub-Images in einem Workflow ein anonymer Pull direkt von Docker Hub und unterliegt dessen Rate-Limit für anonyme Pulls.

Sobald ein Owner das Docker-Hub-Token deiner Organisation im Dependency-Proxy hinterlegt, laufen Docker-Hub-Pulls in deinen Jobs über den Proxy und werden zwischengespeichert, außer in Jobs aus Pull-Requests von Forks. Du kannst auch ausdrücklich über frem.sh/<org>/dependency-proxy/docker.io/ ziehen. Siehe Pull Docker Hub images through the dependency proxy with your own Docker Hub token.

npm audit und pnpm audit über den Dependency-Proxy

npm audit und pnpm audit schicken ihre Audit-Anfrage an die Registry, von der sie installieren. Ist diese Registry der Dependency-Proxy deiner Organisation (https://frem.sh/_app/proxy/<org>/npm/), wie bei Jobs mit eingeschaltetem Runner-Pull-Through, beantwortet der Proxy die Anfrage selbst, im Bulk-Advisory-Format von npm, aus dem eigenen Advisory-Index von fremforge, der aus OSV-Daten aufgebaut ist. Der Anfrage-Body ist deine genaue Abhängigkeitsliste, und der Proxy leitet ihn nicht weiter: Er erreicht nie registry.npmjs.org oder einen anderen Advisory-Dienst eines Drittanbieters. Die Anfrage wird wie jede andere Proxy-Anfrage authentifiziert, mit einem frem.sh-Token, das Pakete in der Organisation lesen darf.

  • Unterstützte Clients: npm 7 und neuer sowie pnpm 11 und neuer. Beide senden POST /-/npm/v1/security/advisories/bulk, den einzigen Audit-Endpunkt, den der Proxy bedient. Der Body darf gzip-komprimiert sein, bis 4 MiB.
  • Nicht unterstützt: npm 6 sowie pnpm 10 und älter nutzen die älteren Audit-Endpunkte (/-/npm/v1/security/audits und /-/npm/v1/security/audits/quick), die der Proxy mit 404 beantwortet. Nutze npm 7 oder neuer bzw. pnpm 11, oder übergib pnpm --ignore-registry-errors.
  • pnpm 11 liest NPM_CONFIG_REGISTRY nicht. Es nimmt seine Registry aus PNPM_CONFIG_REGISTRY, einer .npmrc oder pnpm-workspace.yaml. Runner-Pull-Through trägt den Proxy in die npmrc des Jobs ein, die pnpm 11 liest. Richtest du einen Job selbst mit NPM_CONFIG_REGISTRY auf den Proxy aus, setze PNPM_CONFIG_REGISTRY auf dieselbe URL, sonst installiert pnpm 11 von registry.npmjs.org und schickt auch sein Audit dorthin.
  • Kann der Advisory-Index nicht gelesen werden, antwortet der Proxy mit 503 und Retry-After: 10 statt mit einem leeren Bericht, sodass eine fehlgeschlagene Abfrage das Audit scheitern lässt, statt als „keine Schwachstellen“ gelesen zu werden.
  • Im Bericht verweisen die Advisory-URLs auf osv.dev, und jeder Titel endet mit der OSV-ID (zum Beispiel einer GHSA-ID). Eine als schädlich bekannte Version wird als Malicious package (MAL-…) gemeldet. Die numerische Advisory-id, die npm anzeigt, wird aus der OSV-ID abgeleitet.

Was NICHT zwischengespeichert wird

  • Private Pakete. Der Proxy zieht von npm, PyPI, Go, Maven, NuGet und den anderen Paket-Registrys anonym, bedient also nur öffentliche Pakete, und der eigene Authorization-Header deines Jobs wird nie an den Upstream gesendet. Private ghcr.io- und quay.io-Images sowie Docker Hub und die Red-Hat-Registrys nutzen die eigene Upstream-Zugangsberechtigung deiner Organisation. Für eine private Paket-Registry überschreibst du die passende Variable (NPM_CONFIG_REGISTRY, PIP_INDEX_URL, GOPROXY, …).
  • Dynamische API-Aufrufe. API-Aufrufe im GitHub-Stil (z. B. npm view <package> gegen api.npmjs.org) werden nicht zwischengespeichert, nur die Registry-Endpunkte für Paketdaten.
  • Quell-Repositorys. git clone-Datenverkehr zu GitHub / GitLab / deiner eigenen Forge wird nicht zwischengespeichert. Nutze die Paket-Registry von fremforge (https://frem.sh/api/packages/<org>/<type>/), wenn du die Quelle kontrollierst.
  • Container-Images aus anderen Registrys. Images aus Registrys, die der Dependency-Proxy nicht kennt (gcr.io, eine private Registry), werden direkt gezogen. Docker Hub und die Red-Hat-Registrys werden nur mit der eigenen Zugangsberechtigung deiner Organisation zwischengespeichert; siehe Docker-Hub-Images. Eine private Registry konfigurierst du direkt pro Workflow.

Zu erwartende Leistung

  • Kalter Cache (erster Pull einer neuen Paketversion): ~2–5 s langsamer als upstream; der Cache holt vom Upstream, speichert in OBS und gibt dann zurück. Netto-Latenz = Upstream-Pull + OBS-Schreibvorgang.
  • Warmer Cache (weitere Pulls derselben Version): ~30–60 s schneller als upstream bei einem typischen npm ci-Lauf; der Cache liefert aus OBS in derselben Region.
  • Cache-Horizont: deine Aufbewahrungseinstellung, standardmäßig 90 Tage. Eine zwischengespeicherte Datei, die so lange nicht gezogen wurde, wird entfernt; Paketversionen und Basis-Images, die deine Organisation noch nutzt, bleiben erhalten. Siehe Retention.

Datensouveränität

Der Dependency-Proxy läuft im eu-de-Cluster von fremforge, und sein Speicher ist ein OBS-Bucket in eu-de. Er ist eigene Software von fremforge, gebaut und ausgerollt wie der Rest der Plattform. Pulls vom Upstream sind anonym, es sei denn, deine Organisation hat für diesen Upstream eine eigene Zugangsberechtigung hinterlegt (zum Beispiel für Docker Hub); siehe Upstream credentials.

Was die Upstream-Registrys erhalten, ist unter What the upstream sees beschrieben. Jeder Pull wird im Registry-Zugriffsprotokoll deiner Organisation erfasst (bei CI-Cache-Treffern im Pull-Census). Der AVV deckt beides ab: das Zugriffsprotokoll in Anhang A.6 und die Upstream-Registrys, die auf deine Weisung ausgewählt werden und keine Unterauftragsverarbeiter sind, in Anhang B §B.9.

Status und Vorfallbehandlung

Der Dependency-Proxy wird überwacht. Jeder Job prüft ihn beim Start: Ist er nicht erreichbar, installiert und zieht dieser Job stattdessen über den Egress von fremforge aus den öffentlichen Registrys, und der Rückfall wird protokolliert. Zu erwartende Auswirkung: ~30–60 s zusätzlich pro nicht zwischengespeichertem Pull. Ein Proxy, der mitten in einem Job ausfällt, wird nicht umgangen: npm und pnpm wiederholen die Anfrage, und ein ausgelasteter Proxy antwortet mit 503 und Retry-After (siehe Errors).

Weiterführend

  • Runner-Image: was im gehosteten Runner-Image eingebacken ist (kaniko, buildkit, Sprach-Toolchains)
  • Secrets: wie du Zugangsdaten für private Registrys pro Workflow einbringst
  • Ausgehender Egress, erlaubte Ziele und das Verhalten des Outbound-Proxys sind unter CI-Runner beschrieben