Zum Hauptinhalt springen

Gehostetes Runner-Image

Workflows mit runs-on: fremforge laufen auf einer kurzlebigen VM, einer pro Commit, die aus dem gehosteten Runner-Image bereitgestellt wird. Es ist auf Gleichstand mit ubuntu-latest ausgelegt: dieselbe actions/setup-*-Bedienung wie bei GitHub Actions, dieselben eingebackenen Toolchains, dieselben Scanner und dazu natives Docker für Container-Builds.

Zweischichtige Architektur

Das Runner-Image ist die Boot-Disk der VM – beide Schichten liegen auf derselben Disk und sind ab dem Booten der VM vorhanden, ohne Download pro Job.

SchichtInhaltGröße
SystemschichtDebian-13-Basis + Systemwerkzeuge in jeweils einer Version (Node 24 LTS, Build-Essentials, Scanner, IaC- und Cloud-CLIs, Browser, DB-Clients, nativer Docker-Daemon)~300 MB
hostedtoolcache-SchichtSprach-Runtimes in mehreren Versionen (Node, Go, Python, .NET, Java, Ruby) + Android SDK + Miniconda3 + R~7 GB

setup-*-Actions lösen aus der hostedtoolcache auf, ohne Download pro Job. RUNNER_TOOL_CACHE und AGENT_TOOLSDIRECTORY zeigen bereits auf /opt/hostedtoolcache.

Die Versionsnummern in den Tabellen unten zeigen, welche Major-/Minor-Linien eingebacken sind. Die genau aufgelösten Versionen werden durch den wöchentlichen Rebuild laufend angehoben und bei jedem Rebuild automatisch veröffentlicht – den aktuell veröffentlichten Werkzeugstand findest du im Changelog.

Sprachen – System

Eine aktuelle Version im PATH. Nutze sie direkt, wenn deinem Workflow der Systemstandard genügt.

SpracheVersionHinweise
Node.js24.x (LTS)+ npm, dazu pnpm + yarn über corepack. Neuere/ältere Linien über actions/setup-node – siehe unten
Rustrustup stablerustc + cargo
PowerShell7.xpwsh
PHP8.3+ Composer

Sprachen – mehrere Versionen über setup-*-Actions

Nutze diese actions/setup-*-Actions genau wie auf GitHub-hosted Runnern. Die angeforderte Version wird aus der hostedtoolcache aufgelöst (kein Netzwerkabruf).

ActionEingebackene VersionenWas sie einrichtet
actions/setup-node@v426.x, 24.x, 22.xNode.js + npm; pnpm/yarn über corepack enable aktivieren
actions/setup-go@v51.27.x, 1.26.xGo-Toolchain + Modul-Cache
actions/setup-python@v53.14, 3.13, 3.12Python + pip
actions/setup-dotnet@v410.0, 8.0.NET SDK (parallel installiert, DOTNET_ROOT gesetzt)
actions/setup-java@v4Temurin 25, 21, 17OpenJDK von Adoptium
ruby/setup-ruby@v14.0.x, 3.4.x, 3.3.xRuby (ruby-builder)

Brauchst du eine Version, die wir nicht einbacken (z. B. Node 20.x für ein Altprojekt), können actions/setup-node, actions/setup-go, actions/setup-java und actions/setup-dotnet eine nicht eingebackene Version zur Laufzeit des Jobs herunterladen (langsamer, aber es funktioniert – sie holen generische Linux-Builds). actions/setup-python und ruby/setup-ruby können das nicht: Upstream veröffentlicht für keines von beiden ein Debian-Asset, daher scheitert eine nicht eingebackene Linie sofort, statt auf etwas zurückzufallen. Wähle eine eingebackene Linie oder nutze für einen Einzelfall uv python install <version> (uv ist eingebacken) oder einen container:-Job.

Build-Essentials

Native Node-Module, Python-Wheels mit C-Erweiterungen, Go mit cgo und Rust-Crates mit C-Abhängigkeiten bauen ohne weitere Einrichtung.

build-essential (gcc + make) · clang + lld · cmake · ninja · pkg-config · autoconf · automake · libtool · zstd · linux-headers (über die Basis)

Paketmanager und Projektwerkzeuge

PaketmanagerVersionHinweise
npmmit Node 24 gebündelt
pnpmstandardmäßig 12.14.0Über corepack, bereits aktiviert. Ein packageManager-Pin des Projekts hat Vorrang; siehe pnpm- und Yarn-Versionen
yarnstandardmäßig 4.18.1Über corepack, bereits aktiviert. Für Yarn Classic yarn@1.22.22 pinnen; siehe pnpm- und Yarn-Versionen
pipxDebianInstalliert Python-CLI-Werkzeuge in isolierten venvs
composerlatestPHP
cargoüber rustup verwaltetRust
mvn (Maven)3.9.xJVM
gradle9.5.xJVM

pnpm- und Yarn-Versionen

pnpm und yarn laufen über corepack, das auf dem Runner aktiviert ist. Welche Version ein Job bekommt, hängt davon ab, ob das Projekt eine pinnt:

  • Kein Pin: Ein Job bekommt pnpm 12.14.0 und Yarn 4.18.1. Beide liegen auf dem Runner, ein Download ist also nicht nötig. Bis zum 21.10.2026 bekam ein Job ohne Pin, was zur Laufzeit des Jobs npms latest war – bei Yarn war das Yarn Classic 1.22.
  • Gepinnt: Setze packageManager in deiner package.json, zum Beispiel "packageManager": "pnpm@11.28.6" oder "packageManager": "yarn@1.22.22", und corepack führt genau diese Version aus. pnpm 12.14.0 und 11.28.6 liegen bereits auf dem Runner; jede andere Version wird beim Start des Jobs heruntergeladen.

Über packageManager triffst du die Wahl. Es hält außerdem deinen lokalen Rechner und die CI auf derselben Version. Wenn wir die Standards auf ein neueres Release anheben, kündigen wir das im Changelog an.

IaC

WerkzeugHinweise
tofu (OpenTofu)MPL-2.0-Ersatz für Terraform. Das echte Terraform steht unter BUSL und ist nicht eingebacken; nutze hashicorp/setup-terraform, wenn du ausdrücklich Terraform brauchst.
bicepAzure
pulumiCloud-übergreifend
ansible (ansible-core)Über pipx
sam (AWS SAM CLI)Serverless

Cloud-CLIs

CloudCLIHinweise
AWSaws v2, sam
Google Cloudgcloud, gsutil, bq
Azureaz
T Cloud Public (OTC)tofu + Provider opentelekomcloudOder pip install otc-cli pro Job

Container und Kubernetes

WerkzeugHinweise
docker (CLI + nativer Daemon)Docker läuft nativ auf der VM (kein Sidecar, kein Umweg über DOCKER_HOST) – siehe Container-Builds unten
kanikoDaemonloser, rootloser OCI-Image-Builder
skopeoImages zwischen Registrys kopieren / untersuchen
kubectl
helm
kustomize
kindLokale k8s-Cluster – funktioniert in den meisten Fällen mit dem nativen Docker-Daemon; ergänze das Label dind-privileged, wenn du auf Operationen mit eingeschränkten Capabilities stößt (KVM-Nesting, rohes /dev für verschachtelte Gäste)
teaForgejo-/Gitea-CLI

Sicherheit und Supply Chain

Vorab eingebacken, damit Secret-, CVE-, SBOM- und SAST-Scans keine Einrichtungszeit kosten.

ScannerFindet
gitleaksSecrets in Commits
trivyCVEs in Betriebssystem und Sprachen + IaC-Fehlkonfigurationen
osv-scannerSchwachstellen aus der OSV-Datenbank
cosignSignieren und Prüfen von Container-Images
syftSBOM-Erzeugung (CycloneDX / SPDX)
opengrepSAST (Semgrep-kompatibler Fork). Vorab eingebacken mit den Sprachordnern der GitLab sast-rules unter /opt/sast-rules/: csharp, go, java, javascript, python und scala. Die Regeln stehen unter MIT, außer go, das unter Apache-2.0 steht (von gosec abgeleitet). Nur diese Ordner werden ausgeliefert. Übergib die benötigten an --config; das Wurzelverzeichnis /opt/sast-rules ist kein Regelsatz
scorecardOSSF-Supply-Chain-Scorecard
checkovIaC-Sicherheit (Terraform, CFN, k8s)
cfn-lintCloudFormation-Lint

Linter

shellcheck · shfmt · yamllint · actionlint (prüft die Forgejo-Actions-Workflows, die du auf frem.sh schreibst) · hadolint (Dockerfile)

Browser und E2E

Für Headless-Browsertests:

  • Chromium + chromedriver (Debian-Paket, Versionen aufeinander abgestimmt)
  • Firefox ESR + geckodriver
  • Selenium Server (JAR unter /opt/selenium-server.jar)

Microsoft Edge ist nicht eingebacken – Chromium nutzt dieselbe Blink-Engine; für Tests in der CI ist Chromium gleichwertig.

Datenbank-Clients

postgresql-client · default-mysql-client · sqlite3. Die vollständigen Datenbankserver kommen über services:-Blöcke (ein Docker-Pull von Docker Hub, über den Dependency-Proxy deiner Organisation, wenn sie eine eigene Docker-Hub-Zugangsberechtigung hat; siehe Docker-Hub-Images).

Mobile und Data Science (eingebacken seit 06.06.2026)

WerkzeugVorinstalliertPro Job ergänzen
Android SDKcmdline-tools (latest) + platforms;android-34 + build-tools;34.0.0 + platform-tools unter ANDROID_HOME=/usr/local/lib/android/sdkWeitere API-Level / NDK / Emulatoren über android-actions/setup-android@v3 (nutzt das Vorinstallierte, kein erneuter Download)
R (CRAN)r-base + r-base-dev (Debian-CRAN-Repository, derzeit 4.3.x) unter /opt/hostedtoolcache/R/4.3/x64CRAN-Pakete über Rscript -e 'install.packages(...)' oder r-lib/actions/setup-r-dependencies@v2
Miniconda3conda + Python 3.11 unter CONDA=/opt/hostedtoolcache/Miniconda3/latest/x64Umgebungen + wissenschaftlicher Stack über conda-incubator/setup-miniconda@v3 mit environment-file:
# Android example
- uses: android-actions/setup-android@v3
- run: ./gradlew assembleDebug

# R example
- uses: r-lib/actions/setup-r@v2
- uses: r-lib/actions/setup-r-dependencies@v2
- run: Rscript -e 'testthat::test_local()'

# Miniconda example
- uses: conda-incubator/setup-miniconda@v3
  with:
    environment-file: env.yml
- shell: bash -el {0}
  run: pytest

Was weiterhin NICHT eingebacken ist

Ausgesprochene Nischen- oder schwergewichtige Werkzeuge, die die meisten Workflows nicht brauchen. Installiere sie pro Job:

WerkzeugInstallationswegHinweise
iOS / XcodeNur macOS – nicht unterstützt (fremforge-Runner laufen unter Linux)Eigener Punkt auf der Roadmap für Runner-Stufen
Juliajulia-actions/setup-julia@v2~150 MB Installation pro Job
Swiftswift-actions/setup-swift@v2Swift-Toolchain für Linux
Haskell / GHChaskell-actions/setup@v2
Monoapt-get install mono-completeNur für das alte .NET Framework – .NET 8/10 sind eingebacken
Browser Microsoft EdgeNicht nötig – Chromium ist dieselbe Engine
Lua / Crystal / Nim / Elixirsetup-*-Action pro Job oder apt

Container-Builds

Natives Docker (Standard)

Auf der VM ist der Docker-Daemon installiert und läuft auf dem Host. Deine docker-CLI spricht ihn über den üblichen lokalen Socket an – kein Docker-in-Docker, kein Sidecar, kein Umweg über DOCKER_HOST. Die meisten Workflows für GitHub-hosted Runner funktionieren unverändert – docker build, docker compose, docker pull, mehrstufige Builds, BuildKit-Funktionen.

- run: docker build -t myapp:${{ github.sha }} .
- run: docker compose up -d
- run: docker pull postgres:16

kaniko

Für reine Image-Builds ist kaniko daemonlos (schnellerer Kaltstart, wenn du nicht den ganzen Docker-Daemon brauchst) und verhält sich beim Layer-Caching gegenüber entfernten Registrys besser.

- run: |
    /usr/local/bin/kaniko \
      --context=$GITHUB_WORKSPACE \
      --dockerfile=Dockerfile \
      --destination=registry.example.com/$GITHUB_REPOSITORY:$GITHUB_SHA

Privilegiertes Docker (KVM-Nesting)

Braucht deine Arbeitslast zusätzliche Capabilities über das hinaus, was der Standard-Docker-Benutzer hat (z. B. kind mit KVM-Nesting, testcontainers-Funktionen, die Capabilities zum Anlegen von Namespaces brauchen, /dev-Zugriff für verschachtelte Gäste), ergänze das Label in runs-on:

jobs:
  integration:
    runs-on: [fremforge, dind-privileged]
    steps:
      - run: docker run --privileged kindest/node:v1.31.0 ...

fremforge leitet diese Jobs an einen VM-Typ mit aktivierter verschachtelter Virtualisierung, mit derselben VM-Isolation pro Commit wie bei den Standard-Runnern.

Wie wir den Umfang in ~7 GB liefern, wenn GitHub-hosted ~50 GB braucht

Die GitHub-hosted Images ubuntu-latest sind groß, weil sie Folgendes einbacken:

  1. Mehrere Versionen pro Sprache – wir backen die 3 neuesten unterstützten Linien für Node, Python, Java und Ruby ein und 2 für Go und .NET (~3 GB insgesamt für alle 6 Sprachfamilien). Die Tabellen oben werden von Hand gepflegt und nennen die Linie, nicht den Patch-Stand. Die genauen derzeit eingebackenen Patch-Versionen – bei jeder Änderung aus den Build-Argumenten des Runner-Images erzeugt – findest du in der generierten Werkzeugliste. Weichen die beiden einmal voneinander ab, gilt die generierte Liste. Eine nicht eingebackene Linie lässt sich für Python und Ruby NICHT pro Job herunterladen (siehe Hinweis unten), wähle also aus dem eingebackenen Satz.
  2. Android SDK + NDK (~10 GB bei GitHub-hosted) – wir backen das Kern-SDK ein (cmdline-tools + Platform 34 + build-tools 34.0.0 + platform-tools, ~3 GB). Weitere API-Level, NDK und Emulator-System-Images werden pro Job über setup-android installiert (nutzt das Vorinstallierte).
  3. Vorab gezogene Docker-Images für Service-Container (postgres, mysql, mongo, redis, mssql ~5 GB) – nicht eingebacken. Ein docker pull holt sie von Docker Hub oder über den Dependency-Proxy deiner Organisation (siehe Paket-Caches).
  4. Browser Microsoft Edge – nicht eingebacken (Chromium ist für Tests in der CI dieselbe Engine).
  5. Mono / Julia / Swift / Haskell / Lua / Crystal / Nim / Elixir – nicht eingebacken (Nische, pro Job installieren).
  6. Alte GCC-Versionen, veraltete Toolchains – wir liefern einen aktuellen Satz.

Was wir für typische Workflows gegenüber GitHub-hosted nicht verlieren:

  • Jede gängige Sprache (Node, Python, Go, Java, .NET, Ruby, Rust, PHP, PowerShell)
  • Mobile (Android SDK) und Data Science (Miniconda + R), eingebacken seit 06.06.2026
  • Jede große Cloud-CLI (AWS, Azure, GCP)
  • Jeden gängigen Scanner (Trivy, Gitleaks, OSV, Cosign, Syft, OpenGrep, Scorecard, Checkov)
  • Beide großen Browser + Selenium
  • Docker (nativ, privilegiert über Label)
  • Alle Standard-GitHub-Actions (actions/checkout, actions/setup-*, actions/upload-artifact usw.)

Braucht dein Team etwas, das wir nicht einbacken, wende dich an den Support – von Renovate verfolgte Werkzeuge kommen mit dem nächsten wöchentlichen Rebuild dazu.

Image-Größe, Kaltstart, Rebuild-Rhythmus

  • Wöchentlicher Rebuild: jeden Montag um 06:00 UTC. Renovate schlägt laufend Versionsanhebungen vor; der Montags-Rebuild übernimmt alles, was in dieser Woche gemergt wurde.
  • Trivy-Gate beim Build: CVEs der Stufen HIGH und CRITICAL lassen den Build hart scheitern. Wir liefern nie ein Image mit bekannten, ungepatchten HIGH-/CRITICAL-Befunden aus.
  • Per sha256 gepinnte Downloads: Jeder Binärabruf beim Build wird gegen einen gepinnten sha256 geprüft. Renovate hebt Version und Hash im selben PR an. Weicht der Hash ab, scheitert der Build deutlich sichtbar – das ist das Sicherheitsnetz für die Supply Chain.
  • VM-Kaltstart: ~25 s (ECS-Bereitstellung + Booten aus dem eingebackenen Image). VMs aus dem Warm-Pool (vorab bereitgestellt, im Leerlauf) senken die Wartezeit auf ~5 s, wenn der Pool Kapazität hat.
  • Veröffentlichung des Manifests: Jeder Rebuild veröffentlicht die aufgelösten Werkzeugversionen, den Image-Digest, die Trivy-Zusammenfassung und die CycloneDX-SBOM im Changelog.

Beispiel-Workflow

Ein minimaler Workflow, der alles nutzt:

name: ci

on:
  push:
    branches: [main]
  workflow_dispatch: {}

jobs:
  build-test-scan:
    runs-on: fremforge
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '24'           # resolves from hostedtoolcache, ~1 s
      - run: npm ci && npm test

      - uses: actions/setup-python@v5
        with:
          python-version: '3.13'
      - run: pip install -r requirements.txt && pytest

      - name: SAST + secrets
        run: |
          gitleaks detect --no-banner --redact
          # one --config per language folder; /opt/sast-rules itself is not a rule set
          opengrep scan --config=/opt/sast-rules/python --config=/opt/sast-rules/javascript .

      - name: SBOM
        run: syft scan dir:. -o cyclonedx-json > sbom.json

      - name: Container build
        run: docker build -t myapp:${{ github.sha }} .

Lizenzen und Drittanbieter-Hinweise

Das Image enthält Software von Drittanbietern unter deren eigenen Lizenzen, darunter opengrep (LGPL-2.1, mit Quellcode-Angebot), Node.js und die SAST-Regeln. Die Hinweise, die Namensnennung für Advisory-Daten und die Bezugsquelle für den Quellcode stehen unter Hinweise zu Drittanbieter-Komponenten im Runner-Image. Innerhalb eines Jobs liegen die Lizenzdateien unter /usr/share/licenses/ und /usr/share/doc/<package>/copyright.

Probleme mit dem Runner-Image melden

Fehlt ein Werkzeug, das du erwartet hast, oder stößt du auf ein Problem zur Laufzeit der VM (Ressourcengrenzen, Netzwerk, Capabilities), wende dich an support@frem.sh. Bei Regressionen der gehosteten Runner antworten wir noch am selben Werktag.