Image til hostede runnere
Workflows med runs-on: fremforge kører på en kortlivet VM, én pr. commit, oprettet ud fra image’et til hostede runnere. Det er designet til at matche ubuntu-latest: den samme actions/setup-*-oplevelse, som du kender fra GitHub Actions, de samme forudinstallerede værktøjskæder, de samme scannere og desuden indbygget Docker til container-builds.
Arkitektur i to lag
Runner-image’et er VM’ens boot-disk. Begge lag ligger på den samme disk og er til stede fra det øjeblik, VM’en starter, uden download pr. job.
| Lag | Indhold | Størrelse |
|---|---|---|
| Systemlag | debian 13 som base + systemværktøjer i én version (Node 24 LTS, build essentials, scannere, IaC- og cloud-CLI’er, browsere, databaseklienter, indbygget Docker-daemon) | ca. 300 MB |
| hostedtoolcache-lag | Sprog-runtimes i flere versioner (Node, Go, Python, .NET, Java, Ruby) + Android SDK + Miniconda3 + R | ca. 7 GB |
setup-*-actions henter fra hostedtoolcache uden download pr. job. RUNNER_TOOL_CACHE og AGENT_TOOLSDIRECTORY peger på forhånd på /opt/hostedtoolcache.
Versionsnumrene i tabellerne nedenfor viser, hvilke major/minor-linjer der er bagt ind. De præcise versioner opdateres løbende af den ugentlige genopbygning og offentliggøres automatisk ved hver genopbygning – se changelog for den aktuelt offentliggjorte værktøjsstak.
Sprog – system
Én nyere version på PATH. Brug dem direkte, når dit workflow kan nøjes med systemets standard.
| Sprog | Version | Bemærkninger |
|---|---|---|
| Node.js | 24.x (LTS) | + npm samt pnpm + yarn via corepack. Nyere/ældre serier via actions/setup-node – se nedenfor |
| Rust | rustup stable | rustc + cargo |
| PowerShell | 7.x | pwsh |
| PHP | 8.3 | + Composer |
Sprog – flere versioner via setup-*-actions
Brug disse actions/setup-*-actions præcis som på GitHub-hostede runnere. Den version, du beder om, hentes fra hostedtoolcache (ingen netværkshentning).
| Action | Bagte versioner | Hvad den sætter op |
|---|---|---|
actions/setup-node@v4 | 26.x, 24.x, 22.x | Node.js + npm; aktivér pnpm/yarn med corepack enable |
actions/setup-go@v5 | 1.27.x, 1.26.x | Go-værktøjskæde + modul-cache |
actions/setup-python@v5 | 3.14, 3.13, 3.12 | Python + pip |
actions/setup-dotnet@v4 | 10.0, 8.0 | .NET SDK (side om side, DOTNET_ROOT sat) |
actions/setup-java@v4 | Temurin 25, 21, 17 | OpenJDK fra Adoptium |
ruby/setup-ruby@v1 | 4.0.x, 3.4.x, 3.3.x | Ruby (ruby-builder) |
Har du brug for en version, vi ikke bager ind (f.eks. Node 20.x til et ældre projekt), kan actions/setup-node, actions/setup-go, actions/setup-java og actions/setup-dotnet hente en ikke-bagt version, når jobbet kører (langsommere, men det virker – de henter generiske linux-builds). actions/setup-python og ruby/setup-ruby kan ikke: upstream udgiver ingen debian-pakke til nogen af dem, så en ikke-bagt serie fejler med det samme i stedet for at falde tilbage. Vælg en bagt serie, eller brug uv python install <version> (uv er bagt ind) eller et container:-job til en enkeltstående opgave.
Build essentials
Native node-moduler, Python-wheels med C-udvidelser, Go cgo og Rust-crates med C-afhængigheder bygger uden videre.
build-essential (gcc + make) · clang + lld · cmake · ninja · pkg-config · autoconf · automake · libtool · zstd · linux-headers (via base)
Pakkehåndtering og projektværktøjer
| Pakkehåndtering | Version | Bemærkninger |
|---|---|---|
npm | følger med Node 24 | |
pnpm | 12.14.0 som standard | Via corepack, der allerede er slået til. Et projekts packageManager-pin har forrang; se pnpm- og Yarn-versioner |
yarn | 4.18.1 som standard | Via corepack, der allerede er slået til. Pin yarn@1.22.22 for Yarn Classic; se pnpm- og Yarn-versioner |
pipx | debian | Installerer Python-CLI-værktøjer i isolerede venvs |
composer | nyeste | PHP |
cargo | styret af rustup | Rust |
mvn (Maven) | 3.9.x | JVM |
gradle | 9.5.x | JVM |
pnpm- og Yarn-versioner
pnpm og yarn kører via corepack, som er slået til på runneren. Hvilken version et job får, afhænger af, om projektet pinner en:
- Intet pin: jobbet får pnpm 12.14.0 og Yarn 4.18.1. Begge ligger på runneren, så der skal intet hentes. Indtil 2026-10-21 fik et job uden pin den version, der var npm’s
latest, da jobbet kørte, og for Yarn var det Yarn Classic 1.22. - Med pin: sæt
packageManageri dinpackage.json, for eksempel"packageManager": "pnpm@11.28.6"eller"packageManager": "yarn@1.22.22", så kørercorepackpræcis den version. pnpm 12.14.0 og 11.28.6 ligger allerede på runneren; alle andre versioner hentes, når jobbet starter.
Det er ved at pinne packageManager, du vælger. Det holder også din lokale maskine og CI på samme version. Når vi flytter standarderne til en nyere udgivelse, annonceres ændringen i changelog.
IaC
| Værktøj | Bemærkninger |
|---|---|
tofu (OpenTofu) | MPL-2.0-licenseret erstatning for Terraform. Den rigtige Terraform er BUSL-licenseret og ikke bagt ind; brug hashicorp/setup-terraform, hvis du specifikt har brug for Terraform. |
bicep | Azure |
pulumi | På tværs af clouds |
ansible (ansible-core) | Via pipx |
sam (AWS SAM CLI) | Serverless |
Cloud-CLI’er
| Cloud | CLI | Bemærkninger |
|---|---|---|
| AWS | aws v2, sam | |
| Google Cloud | gcloud, gsutil, bq | |
| Azure | az | |
| T Cloud Public (OTC) | tofu + opentelekomcloud-provideren | Eller pip install otc-cli pr. job |
Containere og Kubernetes
| Værktøj | Bemærkninger |
|---|---|
docker (CLI + indbygget daemon) | Docker kører direkte på VM’en (ingen sidecar, ingen omvej via DOCKER_HOST) – se Container-builds nedenfor |
kaniko | Daemonløs, rootless OCI-image-builder |
skopeo | Kopiering/inspektion af images mellem registries |
kubectl | |
helm | |
kustomize | |
kind | Lokale k8s-klynger – virker i de fleste tilfælde med den indbyggede Docker-daemon; tilføj labelen dind-privileged, hvis du rammer operationer, der kræver ekstra capabilities (KVM-nesting, rå /dev til indlejrede gæster) |
tea | Forgejo/Gitea-CLI |
Sikkerhed og forsyningskæde
Bagt ind på forhånd, så scanninger for secrets, CVE’er, SBOM og SAST ikke koster opsætningstid.
| Scanner | Fanger |
|---|---|
gitleaks | Secrets i commits |
trivy | CVE’er i OS og sprog + fejlkonfiguration af IaC |
osv-scanner | Sårbarheder fra OSV-databasen |
cosign | Signering og verificering af container-images |
syft | Generering af SBOM (CycloneDX / SPDX) |
opengrep | SAST (Semgrep-kompatibel fork). Bagt ind med GitLab sast-rules’ sprogmapper under /opt/sast-rules/: csharp, go, java, javascript, python og scala. Reglerne er MIT, bortset fra go, som er Apache-2.0 (afledt af gosec). Kun de mapper følger med. Angiv dem, du har brug for, med --config; roden af /opt/sast-rules er ikke et regelsæt |
scorecard | OSSF supply-chain scorecard |
checkov | IaC-sikkerhed (Terraform, CFN, k8s) |
cfn-lint | Lint af CloudFormation |
Linters
shellcheck · shfmt · yamllint · actionlint (linter de Forgejo Actions-workflows, du skriver på frem.sh) · hadolint (Dockerfile)
Browsere og e2e
Til headless browsertests:
- Chromium +
chromedriver(debian-pakket, matchende versioner) - Firefox ESR +
geckodriver - Selenium Server (jar-fil i
/opt/selenium-server.jar)
Microsoft Edge er ikke bagt ind – Chromium bruger den samme Blink-motor, så til test i CI svarer Chromium til Edge.
Databaseklienter
postgresql-client · default-mysql-client · sqlite3. De fulde databaseservere kommer via services:-blokke (et Docker-pull fra Docker Hub, gennem din organisations dependency proxy, når den har sine egne Docker Hub-legitimationsoplysninger; se Docker Hub-images).
Mobil og datavidenskab (bagt ind siden 2026-06-06)
| Værktøj | Forudinstalleret | Tilføj pr. job |
|---|---|---|
| Android SDK | cmdline-tools (latest) + platforms;android-34 + build-tools;34.0.0 + platform-tools i ANDROID_HOME=/usr/local/lib/android/sdk | Flere API-niveauer / NDK / emulatorer via android-actions/setup-android@v3 (genbruger det forudinstallerede, ingen ny download) |
| R (CRAN) | r-base + r-base-dev (debians CRAN-repo, i øjeblikket 4.3.x) i /opt/hostedtoolcache/R/4.3/x64 | CRAN-pakker via Rscript -e 'install.packages(...)' eller r-lib/actions/setup-r-dependencies@v2 |
| Miniconda3 | conda + python 3.11 i CONDA=/opt/hostedtoolcache/Miniconda3/latest/x64 | Miljøer og videnskabelig stak via conda-incubator/setup-miniconda@v3 med 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: pytestHvad der stadig IKKE er bagt ind
Virkelig nicheprægede eller tunge værktøjer, som de fleste workflows ikke har brug for. Installér dem pr. job:
| Værktøj | Installation | Bemærkninger |
|---|---|---|
| iOS / Xcode | Kun macOS – understøttes ikke (fremforges runnere er Linux) | Særskilt punkt på køreplanen for runner-niveauer |
| Julia | julia-actions/setup-julia@v2 | ca. 150 MB installation pr. job |
| Swift | swift-actions/setup-swift@v2 | Swift-værktøjskæde til Linux |
| Haskell / GHC | haskell-actions/setup@v2 | |
| Mono | apt-get install mono-complete | Kun ældre .NET Framework – .NET 8/10 er bagt ind |
| Microsoft Edge-browseren | Ikke nødvendig – Chromium er den samme motor | |
| Lua / Crystal / Nim / Elixir | setup-*-action eller apt pr. job |
Container-builds
Indbygget Docker (standard)
VM’en leveres med Docker-daemonen installeret og kørende på værten. Din docker-CLI taler med den over den almindelige lokale socket – ingen Docker-in-Docker, ingen sidecar, ingen omvej via DOCKER_HOST. De fleste workflows til GitHub-hostede runnere virker uændret – docker build, docker compose, docker pull, multi-stage-builds og BuildKit-funktioner.
- run: docker build -t myapp:${{ github.sha }} .
- run: docker compose up -d
- run: docker pull postgres:16kaniko
Til rene image-builds er kaniko daemonløs (hurtigere kold start, når du ikke har brug for hele Docker-daemonen) og har bedre lag-cache-adfærd mod eksterne registries.
- run: |
/usr/local/bin/kaniko \
--context=$GITHUB_WORKSPACE \
--dockerfile=Dockerfile \
--destination=registry.example.com/$GITHUB_REPOSITORY:$GITHUB_SHAPrivilegeret Docker (KVM-nesting)
Har din arbejdsbyrde brug for ekstra capabilities ud over dem, standard-Docker-brugeren får (f.eks. kind med KVM-nesting, testcontainers-funktioner, der kræver capabilities til at oprette namespaces, eller adgang til /dev for indlejrede gæster), så tilføj labelen til runs-on:
jobs:
integration:
runs-on: [fremforge, dind-privileged]
steps:
- run: docker run --privileged kindest/node:v1.31.0 ...fremforge sender disse jobs til en VM-type med indlejret virtualisering slået til, med den samme VM-isolation pr. commit som standardrunnerne.
Sådan leverer vi dækningen på ca. 7 GB, når GitHub-hosted fylder ca. 50 GB
GitHub-hostede ubuntu-latest-images er store, fordi de bager følgende ind:
- Flere versioner pr. sprog – vi bager de 3 nyeste understøttede serier ind for Node, Python, Java og Ruby og 2 for Go og .NET (ca. 3 GB i alt for alle 6 sprogfamilier). Tabellerne ovenfor vedligeholdes i hånden og nævner serien, ikke patch-versionen. De præcise patch-versioner, der er bagt ind lige nu – genereret ud fra runner-image’ets egne build-argumenter ved hver ændring – finder du i den genererede liste over værktøjsstakken. Er de to nogensinde uenige, er det den genererede liste, der har ret. En ikke-bagt serie kan IKKE hentes pr. job for Python eller Ruby (se bemærkningen nedenfor), så vælg blandt de bagte.
- Android SDK + NDK (ca. 10 GB på GitHub-hosted) – vi bager kerne-SDK’et ind (cmdline-tools + platform 34 + build-tools 34.0.0 + platform-tools, ca. 3 GB). Flere API-niveauer, NDK og emulator-systemimages installeres pr. job via
setup-android(som genbruger det forudinstallerede). - Forhåndshentede Docker-images til service-containere (postgres, mysql, mongo, redis, mssql, ca. 5 GB) – ikke bagt ind. Et
docker pullhenter dem fra Docker Hub eller gennem din organisations dependency proxy (se pakke-caches). - Microsoft Edge-browseren – ikke bagt ind (Chromium er den samme motor, når det gælder test i CI).
- Mono / Julia / Swift / Haskell / Lua / Crystal / Nim / Elixir – ikke bagt ind (niche, installér pr. job).
- Ældre GCC-versioner og udfasede værktøjskæder – vi leverer ét aktuelt sæt.
Hvad vi ikke mister i forhold til GitHub-hosted for typiske workflows:
- Alle gængse sprog (Node, Python, Go, Java, .NET, Ruby, Rust, PHP, PowerShell)
- Mobil (Android SDK) og datavidenskab (Miniconda + R), bagt ind siden 2026-06-06
- Alle store cloud-CLI’er (AWS, Azure, GCP)
- Alle gængse scannere (Trivy, Gitleaks, OSV, Cosign, Syft, OpenGrep, Scorecard, Checkov)
- Begge store browsere + Selenium
- Docker (indbygget, privilegeret via label)
- Alle standard-GitHub Actions (
actions/checkout,actions/setup-*,actions/upload-artifactosv.)
Har dit team brug for noget, vi ikke bager ind, så kontakt support – værktøjer, som Renovate følger, kommer med i den næste ugentlige genopbygning.
Image-størrelse, kold start og genopbygningsrytme
- Ugentlig genopbygning: hver mandag kl. 06:00 UTC. Renovate foreslår løbende versionsopdateringer; mandagens genopbygning tager alt med, der er merget i løbet af ugen.
- Trivy-gate ved build: CVE’er med HIGH og CRITICAL får buildet til at fejle. Vi leverer aldrig et image med kendte, ulappede HIGH/CRITICAL-fund.
- sha256-pinnede downloads: hver binærfil, der hentes under buildet, verificeres mod en pinnet sha256. Renovate opdaterer version og hash i den samme pull request. Buildet fejler højlydt, hvis hashen afviger – det er sikkerhedsnettet for forsyningskæden.
- Kold start af VM: ca. 25 s (ECS-oprettelse + boot fra det bagte image). VM’er i en varm pulje (oprettet på forhånd og i tomgang) får ventetiden ned på ca. 5 s, når puljen har kapacitet.
- Offentliggørelse af manifest: hver genopbygning offentliggør de opløste værktøjsversioner, image-digest, Trivy-opsummering og CycloneDX-SBOM i changelog.
Eksempel på et workflow
Et minimalt workflow, der “bruger det hele”:
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 }} .Licenser og tredjepartsmeddelelser
Image’et indeholder tredjepartssoftware under deres egne licenser, blandt andet opengrep (LGPL-2.1, med et kildekodetilbud), Node.js og SAST-reglerne. Meddelelserne, kildeangivelsen for advisory-data og oplysninger om, hvor du får kildekoden, står på Tredjepartsmeddelelser for runner-image’et. Inde i et job ligger licensfilerne under /usr/share/licenses/ og /usr/share/doc/<package>/copyright.
Rapportering af problemer med runner-image’et
Mangler et værktøj, du forventede, eller rammer du et problem med VM-kørslen (ressourcegrænser, netværk, capabilities), så kontakt support@frem.sh. Vi svarer samme hverdag ved regressioner i hostede runnere.