Naar de hoofdinhoud

Gehoste runner-image

Workflows met runs-on: fremforge draaien op een tijdelijke VM, één per commit, die wordt ingericht vanuit de gehoste runner-image. Die is ontworpen voor gelijkwaardigheid met ubuntu-latest: dezelfde actions/setup-*-ervaring als op GitHub Actions, dezelfde ingebakken toolchains, dezelfde scanners, plus native Docker voor containerbuilds.

Architectuur met twee lagen

De runner-image is de opstartschijf van de VM: beide lagen staan op dezelfde schijf en zijn aanwezig vanaf het moment dat de VM opstart, zonder download per job.

LaagWat erin zitGrootte
Systeemlaagdebian 13-basis + systeemtools in één versie (Node 24 LTS, build essentials, scanners, IaC- en cloud-CLI’s, browsers, databaseclients, native Docker-daemon)~300 MB
hostedtoolcache-laagTaalruntimes in meerdere versies (Node, Go, Python, .NET, Java, Ruby) + Android SDK + Miniconda3 + R~7 GB

setup-*-actions halen hun versie uit de hostedtoolcache, zonder download per job. RUNNER_TOOL_CACHE en AGENT_TOOLSDIRECTORY wijzen al naar /opt/hostedtoolcache.

De versienummers in de tabellen hieronder geven aan welke hoofd- en subversielijnen zijn ingebakken. De exacte versies worden continu bijgewerkt door de wekelijkse herbouw en bij elke herbouw automatisch gepubliceerd; zie de changelog voor de actueel gepubliceerde toolstack.

Talen: systeem

Eén recente versie op het PATH. Gebruik die rechtstreeks als je workflow tevreden is met de systeemstandaard.

TaalVersieOpmerkingen
Node.js24.x (LTS)+ npm, plus pnpm + yarn via corepack. Nieuwere/oudere reeksen via actions/setup-node; zie hieronder
Rustrustup stablerustc + cargo
PowerShell7.xpwsh
PHP8.3+ Composer

Talen: meerdere versies via setup-*-actions

Gebruik deze actions/setup-*-actions precies zoals op de door GitHub gehoste runners. De versie die je vraagt, komt uit de hostedtoolcache (geen ophalen via het netwerk).

ActionIngebakken versiesWat het inricht
actions/setup-node@v426.x, 24.x, 22.xNode.js + npm; activeer pnpm/yarn met corepack enable
actions/setup-go@v51.27.x, 1.26.xGo-toolchain + modulecache
actions/setup-python@v53.14, 3.13, 3.12Python + pip
actions/setup-dotnet@v410.0, 8.0.NET SDK (naast elkaar, DOTNET_ROOT gezet)
actions/setup-java@v4Temurin 25, 21, 17OpenJDK van Adoptium
ruby/setup-ruby@v14.0.x, 3.4.x, 3.3.xRuby (ruby-builder)

Heb je een versie nodig die we niet inbakken (bijv. Node 20.x voor een ouder project), dan kunnen actions/setup-node, actions/setup-go, actions/setup-java en actions/setup-dotnet een niet-ingebakken versie tijdens de job downloaden (trager, maar het werkt: ze halen generieke Linux-builds op). actions/setup-python en ruby/setup-ruby kunnen dat niet: upstream publiceert voor geen van beide een debian-asset, dus een niet-ingebakken reeks faalt meteen in plaats van terug te vallen. Kies een ingebakken reeks, of gebruik uv python install <version> (uv is ingebakken) of een container:-job voor een eenmalig geval.

Build essentials

Native Node-modules, Python-wheels met C-extensies, Go met cgo en Rust-crates met C-dependencies bouwen direct.

build-essential (gcc + make) · clang + lld · cmake · ninja · pkg-config · autoconf · automake · libtool · zstd · linux-headers (via de basis)

Pakketbeheerders en projecttools

PakketbeheerderVersieOpmerkingen
npmmeegeleverd met Node 24
pnpmstandaard 12.14.0Via corepack, staat al aan. Een packageManager-pin van het project gaat voor; zie Versies van pnpm en Yarn
yarnstandaard 4.18.1Via corepack, staat al aan. Pin yarn@1.22.22 voor Yarn Classic; zie Versies van pnpm en Yarn
pipxdebianInstalleert Python-CLI-tools in geïsoleerde venvs
composernieuwstePHP
cargobeheerd door rustupRust
mvn (Maven)3.9.xJVM
gradle9.5.xJVM

Versies van pnpm en Yarn

pnpm en yarn draaien via corepack, dat op de runner aanstaat. Welke versie een job krijgt, hangt ervan af of het project er een vastzet:

  • Geen pin: een job krijgt pnpm 12.14.0 en Yarn 4.18.1. Beide staan op de runner, dus er is geen download nodig. Tot 2026-10-21 kreeg een job zonder pin wat latest van npm op dat moment was, en dat was voor Yarn de Yarn Classic 1.22.
  • Met pin: zet packageManager in je package.json, bijvoorbeeld "packageManager": "pnpm@11.28.6" of "packageManager": "yarn@1.22.22", en corepack draait precies die versie. pnpm 12.14.0 en 11.28.6 staan al op de runner; elke andere versie wordt gedownload wanneer de job start.

Met packageManager vastzetten kies je zelf. Het houdt ook je lokale machine en CI op dezelfde versie. Wanneer we de standaardversies naar een nieuwere release verplaatsen, kondigen we dat aan in de changelog.

IaC

ToolOpmerkingen
tofu (OpenTofu)MPL-2.0-vervanger voor Terraform. Het echte Terraform valt onder de BUSL-licentie en is niet ingebakken; gebruik hashicorp/setup-terraform als je specifiek Terraform nodig hebt.
bicepAzure
pulumiVoor meerdere clouds
ansible (ansible-core)Via pipx
sam (AWS SAM CLI)Serverless

Cloud-CLI’s

CloudCLIOpmerkingen
AWSaws v2, sam
Google Cloudgcloud, gsutil, bq
Azureaz
T Cloud Public (OTC)tofu + provider opentelekomcloudOf pip install otc-cli per job

Containers en Kubernetes

ToolOpmerkingen
docker (CLI + native daemon)Docker draait native op de VM (geen sidecar, geen omweg via DOCKER_HOST); zie Containerbuilds hieronder
kanikoRootless OCI-imagebouwer zonder daemon
skopeoImages kopiëren / inspecteren tussen registries
kubectl
helm
kustomize
kindLokale k8s-clusters; werkt in de meeste gevallen met de native Docker-daemon; voeg het label dind-privileged toe als je tegen handelingen aanloopt die extra capabilities vereisen (KVM-nesting, rauwe /dev voor geneste gasten)
teaCLI voor Forgejo / Gitea

Beveiliging en toeleveringsketen

Vooraf ingebakken, zodat scans op secrets, CVE’s, SBOM en SAST geen tijd voor inrichting kosten.

ScannerVindt
gitleaksSecrets in commits
trivyCVE’s in OS en talen + misconfiguratie in IaC
osv-scannerKwetsbaarheden uit de OSV-database
cosignOndertekenen en verifiëren van container-images
syftSBOM’s genereren (CycloneDX / SPDX)
opengrepSAST (Semgrep-compatibele fork). Vooraf ingebakken met de taalmappen van GitLab sast-rules onder /opt/sast-rules/: csharp, go, java, javascript, python en scala. De regels vallen onder MIT, behalve go, dat onder Apache-2.0 valt (afgeleid van gosec). Alleen die mappen worden meegeleverd. Geef de mappen die je nodig hebt mee aan --config; de root van /opt/sast-rules is geen regelset
scorecardOSSF-scorecard voor de toeleveringsketen
checkovIaC-beveiliging (Terraform, CFN, k8s)
cfn-lintLint voor CloudFormation

Linters

shellcheck · shfmt · yamllint · actionlint (lint de Forgejo Actions-workflows die je op frem.sh schrijft) · hadolint (Dockerfile)

Browsers en e2e

Voor headless browsertests:

  • Chromium + chromedriver (debian-pakket, met bijpassende versie)
  • Firefox ESR + geckodriver
  • Selenium Server (jar op /opt/selenium-server.jar)

Microsoft Edge is niet ingebakken: Chromium gebruikt dezelfde Blink-engine, dus voor tests in CI is Chromium gelijkwaardig.

Databaseclients

postgresql-client · default-mysql-client · sqlite3. De volledige databaseservers komen via services:-blokken (een Docker-pull van Docker Hub, via de dependency-proxy van je organisatie als die eigen Docker Hub-inloggegevens heeft; zie Images van Docker Hub).

Mobiel en datawetenschap (ingebakken sinds 2026-06-06)

ToolWat er vooraf is geïnstalleerdPer job toevoegen
Android SDKcmdline-tools (latest) + platforms;android-34 + build-tools;34.0.0 + platform-tools op ANDROID_HOME=/usr/local/lib/android/sdkExtra API-niveaus / NDK / emulators via android-actions/setup-android@v3 (hergebruikt wat al is geïnstalleerd, geen nieuwe download)
R (CRAN)r-base + r-base-dev (debian-CRAN-repository, momenteel 4.3.x) op /opt/hostedtoolcache/R/4.3/x64CRAN-pakketten via Rscript -e 'install.packages(...)' of r-lib/actions/setup-r-dependencies@v2
Miniconda3conda + python 3.11 op CONDA=/opt/hostedtoolcache/Miniconda3/latest/x64Omgevingen + wetenschappelijke stack via conda-incubator/setup-miniconda@v3 met 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

Wat er nog NIET is ingebakken

Echt nichegerichte of zware tools die de meeste workflows niet nodig hebben. Installeer ze per job:

ToolInstallatierouteOpmerkingen
iOS / XcodeAlleen macOS: niet ondersteund (fremforge-runners zijn Linux)Apart punt op de roadmap voor runnerniveaus
Juliajulia-actions/setup-julia@v2~150 MB installatie per job
Swiftswift-actions/setup-swift@v2Swift-toolchain voor Linux
Haskell / GHChaskell-actions/setup@v2
Monoapt-get install mono-completeAlleen het oude .NET Framework; .NET 8/10 zijn ingebakken
Browser Microsoft EdgeNiet nodig: Chromium is dezelfde engine
Lua / Crystal / Nim / Elixirsetup-*-action of apt per job

Containerbuilds

Native Docker (standaard)

De VM wordt geleverd met de Docker-daemon geïnstalleerd en draaiend op de host. Je docker-CLI praat ermee via de standaard lokale socket: geen Docker-in-Docker, geen sidecar, geen omweg via DOCKER_HOST. De meeste workflows voor door GitHub gehoste runners werken ongewijzigd: docker build, docker compose, docker pull, multi-stage builds, BuildKit-functies.

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

kaniko

Voor pure imagebuilds werkt kaniko zonder daemon (snellere koude start als je niet de hele Docker-daemon nodig hebt) en gaat het beter om met de laagcache bij externe registries.

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

Docker met extra rechten (KVM-nesting)

Heeft je workload extra capabilities nodig naast wat de standaard Docker-gebruiker krijgt (bijv. kind met KVM-nesting, functies van testcontainers die capabilities voor het aanmaken van namespaces vereisen, toegang tot /dev voor geneste gasten), voeg dan het label toe aan runs-on:

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

fremforge stuurt deze jobs naar een VM-type met geneste virtualisatie, met dezelfde isolatie van één VM per commit als de standaardrunners.

Hoe we in ~7 GB dekken waar GitHub ~50 GB voor gebruikt

De ubuntu-latest-images van GitHub zijn groot omdat ze het volgende inbakken:

  1. Meerdere versies per taal: wij bakken de 3 meest recente ondersteunde reeksen in voor Node, Python, Java en Ruby, en 2 voor Go en .NET (~3 GB in totaal voor alle 6 taalfamilies). De tabellen hierboven worden met de hand bijgehouden en noemen de reeks, niet de patchversie. Voor de exacte patchversies die nu zijn ingebakken, bij elke wijziging gegenereerd uit de eigen buildargumenten van de runner-image, zie de gegenereerde toolstacklijst. Spreken de twee elkaar ooit tegen, dan heeft de gegenereerde lijst gelijk. Een niet-ingebakken reeks kan voor Python en Ruby NIET per job worden gedownload (zie de opmerking hieronder), dus kies uit de ingebakken set.
  2. Android SDK + NDK (~10 GB bij GitHub): wij bakken de kern-SDK in (cmdline-tools + platform 34 + build-tools 34.0.0 + platform-tools, ~3 GB). Extra API-niveaus, NDK en systeemimages voor emulators installeer je per job via setup-android (hergebruikt wat al is geïnstalleerd).
  3. Vooraf opgehaalde Docker-images voor servicecontainers (postgres, mysql, mongo, redis, mssql ~5 GB): niet ingebakken. Een docker pull haalt ze op van Docker Hub, of via de dependency-proxy van je organisatie (zie pakketcaches).
  4. De browser Microsoft Edge: niet ingebakken (Chromium is voor tests in CI dezelfde engine).
  5. Mono / Julia / Swift / Haskell / Lua / Crystal / Nim / Elixir: niet ingebakken (niche, per job te installeren).
  6. Oude GCC-versies, verouderde toolchains: wij leveren één actuele set.

Wat we voor gewone workflows niet inleveren ten opzichte van GitHub:

  • Elke gangbare taal (Node, Python, Go, Java, .NET, Ruby, Rust, PHP, PowerShell)
  • Mobiel (Android SDK) en datawetenschap (Miniconda + R), ingebakken sinds 2026-06-06
  • Elke grote cloud-CLI (AWS, Azure, GCP)
  • Elke gangbare scanner (Trivy, Gitleaks, OSV, Cosign, Syft, OpenGrep, Scorecard, Checkov)
  • Beide grote browsers + Selenium
  • Docker (native, met extra rechten via een label)
  • Alle standaard GitHub Actions (actions/checkout, actions/setup-*, actions/upload-artifact, enz.)

Heeft je team iets nodig wat we niet inbakken, neem contact op met support; tools die Renovate volgt, gaan mee in de volgende wekelijkse herbouw.

Grootte van de image, koude start, herbouwritme

  • Wekelijkse herbouw: elke maandag om 06:00 UTC. Renovate stelt continu versie-updates voor; de herbouw op maandag neemt alles mee wat die week is gemerged.
  • Trivy-poort tijdens de build: HIGH- en CRITICAL-CVE’s laten de build hard falen. We leveren nooit een image met bekende, niet-gepatchte HIGH/CRITICAL-bevindingen.
  • Downloads vastgezet met sha256: elke binary die tijdens de build wordt opgehaald, wordt gecontroleerd tegen een vastgezette sha256. Renovate werkt de versie en de hash in dezelfde PR bij. De build faalt luid bij een afwijkende hash; dat is het vangnet voor de toeleveringsketen.
  • Koude start van de VM: ~25 s (ECS-inrichting + opstarten vanuit de ingebakken image). VM’s uit een warme pool (vooraf ingericht en klaarstaand) brengen de wachttijd terug tot ~5 s als de pool capaciteit heeft.
  • Publicatie van het manifest: elke herbouw publiceert de opgeloste toolversies, de image-digest, de Trivy-samenvatting en de CycloneDX-SBOM in de changelog.

Voorbeeldworkflow

Een minimale workflow die “alles gebruikt”:

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 }} .

Licenties en vermeldingen van derden

De image bevat software van derden onder hun eigen licenties, waaronder opengrep (LGPL-2.1, met een bronaanbod), Node.js en de SAST-regels. De vermeldingen, de naamsvermelding voor advisorygegevens en waar je de broncode krijgt, staan op Vermeldingen van derden in de runner-image. Binnen een job staan de licentiebestanden onder /usr/share/licenses/ en /usr/share/doc/<package>/copyright.

Problemen met de runner-image melden

Ontbreekt een tool die je verwachtte, of loop je tegen een probleem in de VM-runtime aan (resourcelimieten, netwerk, capabilities), neem dan contact op met support@frem.sh. Bij regressies in de gehoste runners reageren we op dezelfde werkdag.