Prebaked Runner Images
A prebaked image is a provider machine image (AWS AMI, Hetzner snapshot, and so on) with the stable parts of a runner already installed, so a lease boots ready instead of installing tooling on every warmup.
Managed Linux also reuses fully installed optional desktop packages and a package-installed Chrome or Chromium that passes its functional version check. Browser signing-key downloads and repository refreshes run only when a usable installed browser is absent. Maintain browser versions through image updates or rebakes; each lease still receives current configuration and readiness checks.
Read this when you are:
- deciding what belongs in a provider image versus a warm lease or a repo cache;
- speeding up
crabbox warmupandcrabbox runfor desktop or browser QA; - planning to bake or promote a Crabbox runner image.
The guiding rule: prebaked images store machine capabilities, not scenario state. Tools, browsers, and OS patches go in the image. Checkouts, dependency caches, credentials, and login state stay out.
For the exact AWS bake, smoke, promotion, rollback, and cleanup commands, follow the Image bake runbook. This page covers the underlying model.
#Where images live
Provider-owned image storage is always the source of truth for image bytes:
- AWS — AMIs and their backing EBS snapshots live in the AWS account.
crabbox image createbuilds a candidate AMI from a lease, andcrabbox image promoterecords the selected AMI as the default for matching brokered AWS leases. Promotion is scoped by target, architecture, and region, so a macOS AMI never replaces the Linux or Windows default. Promotions may declare OS, SDK/runtime, browser, WebView2, and desktop capabilities. Capability-aware leases select the newest matching AMI from the scoped promotion catalog and fail before leasing when no image matches. - Azure — managed OS disk snapshots live in the subscription. A native
crabbox checkpoint createcaptures the snapshot;crabbox image promote --provider azurerecords it as the default for matching target, architecture, VM size, OS, and location.crabbox image delete --provider azureremoves Crabbox-owned snapshots. - GCP — machine images and disk snapshots live in the cloud project.
crabbox image createcan capture them andcrabbox image delete --provider gcpcan remove them. - Hetzner — snapshots live in the Hetzner project. A direct native checkpoint can create, verify, delete, and fork one; brokered Hetzner checkpoints remain workspace archives.
image createandimage promoteremain coordinator operations and are unsupported for Hetzner. Directimage delete --provider hetzneris limited to a snapshot claimed by exactly one localhetzner-snapshotcheckpoint record. - Delegated runners (for example Blacksmith) — images are owned by the provider's runner infrastructure, not by Crabbox.
The coordinator stores scoped provider image identifiers, promotion capability metadata, and enough tags to explain provenance. Do not store image bytes in git, release artifacts, or coordinator durable state.
#What to bake
Bake stable machine capabilities:
- current OS security updates and base packages;
- core access tooling: SSH, Git, rsync, curl, jq, tmux,
flock, and the system CA bundle; - desktop and browser capabilities for
--desktop --browserleases (resize-capable TigerVNC, slim XFCE, Chrome or Chromium); - capture tools such as
ffmpeg,ffprobe,scrot, andxdotool; - language and build toolchains the image targets: Node 24 with corepack/pnpm,
build-essential, Python, and common native-addon headers; - Docker Engine and supporting plugins where the platform runs headless Docker;
- empty shared cache directories such as
/var/cache/crabbox/pnpm.
The bundled Linux developer-image prep runs the standalone generated readiness producer only after installing and proving the complete managed Debian/Ubuntu baseline. It atomically writes the strict root-owned /var/lib/crabbox-readiness/linux.json capability manifest and a compatibility /var/lib/crabbox/image-ready marker. linux-minimal covers the eight baseline packages and their functional probes; linux-builder additionally proves generic native-build, Git LFS, package-config, and Python virtual-environment capabilities. The Python probe creates a disposable pip-enabled virtual environment and runs its pip before cleaning up. Images missing a builder capability are truthfully downgraded to linux-minimal, while images missing a baseline capability cannot be marked. Developer-image preparation and publication require linux-builder: a minimal claim is not accepted as a developer image. The publisher uploads its trusted source verifier for source, candidate, and promoted leases; verification never repairs or downgrades the manifest.
Later boots verify exact canonical manifest bytes, its trusted non-symlink path, root ownership/group, file mode and bounded size, and every declared profile probe under a sanitized system PATH before skipping the baseline APT transaction. The readiness directory and its entire parent chain are root-controlled; the separate legacy marker directory may belong to the runtime user, so the marker is only a compatibility hint. Its exact root-owned bytes permit migration only when no manifest exists and every baseline probe independently passes, without APT or dpkg work. Invalid existing manifests cannot be rescued by a marker. This is local capability evidence, not package-version attestation, signed provenance, tenant isolation, or typed-pool identity. Per-lease users, SSH keys, work roots, optional services, and readiness checks still run normally.
Do not bake scenario state:
- secrets, tokens, or provider credentials;
- browser profiles, cookies, OAuth state, or chat/login sessions;
- repository checkouts,
node_modules, builtdist/, or PR artifacts; - one-off operator notes or debugging files.
Anything that varies per repository, per lockfile, or per run does not belong in a shared image.
#Runtime caches belong outside the image
Dependency state changes far more often than machine capabilities, so it lives outside the image:
- a warm lease can keep
/var/cache/crabbox/pnpmand browser profiles for a short-lived operator session; - GitHub Actions should cache candidate pnpm stores by lockfile and platform;
- product-specific runtime bundles and evidence belong in the workflow workspace, for example under
.artifacts/; - long-lived reusable volumes should be keyed by repo, lockfile, runtime version, platform, and image id before Crabbox mounts them into leases.
This split keeps one image reusable across many repositories while still letting slow QA lanes skip repeated dependency work when they deliberately reuse a warm lease or a keyed external cache.
#Operator flow
The Image bake runbook has the precise commands and guard scripts. At a high level, an AWS bake is:
- Warm a fresh source lease with the capabilities the image must provide:
``bash crabbox warmup --provider aws --class standard --desktop --browser \ --ttl 2h --idle-timeout 30m ``
- Verify the machine capability contract on that lease (tools, browser, directories) over
crabbox run --no-sync --shell. - Create a candidate AMI from the lease's canonical
cbx_...id:
``bash crabbox image create --id <cbx_id> --name my-org-linux-desktop-YYYYMMDD-HHMM \ --wait --json ``
- Boot the candidate explicitly through an image override and smoke it:
``bash CRABBOX_AWS_AMI=ami-1234567890abcdef0 \ crabbox warmup --provider aws --class standard --desktop --browser \ --ttl 30m --idle-timeout 10m ``
- Promote the candidate once the smoke passes:
``bash crabbox image promote ami-1234567890abcdef0 --json ``
Add declarations such as --os-version 26.04 --runtime node=24.2 --browser --desktop when future leases must select by baked capabilities.
- Run a normal brokered lease (no override) plus the relevant QA lane. The CLI prints
image selected id=... source=promoted; require the exact promoted ID in publication proof. - Keep the previous known-good AMI until the new image has real QA proof.
A successful bake is not just "the browser exists." A useful image measurably reduces crabbox warmup and crabbox run time in your timing evidence while keeping credentials, login state, and repository artifacts out of the image.
#Image commands
Image creation, promotion, Fast Snapshot Restore, and AWS/Azure/GCP deletion require coordinator admin auth and can create or remove paid provider-side artifacts. The direct Hetzner deletion exception is described below.
crabbox image create --id <cbx_id> --name <name> [--wait]— capture a provider image from a lease (--no-rebootdefaults to true on AWS).crabbox image promote <image-id> [--provider aws|azure] [--target linux|macos|windows] [--region <r>]— set a scoped brokered AWS AMI or Azure OS disk snapshot default. AWS supports--fast-snapshot-restorewith--fsr-az <az>and capability declarations.crabbox image fsr-status <ami-id|snapshot-id>— AWS Fast Snapshot Restore status.crabbox image delete <image-id> [--provider aws|azure|gcp|hetzner]— remove a Crabbox-created provider image. Deletion requires stored Crabbox ownership metadata and refuses unrelated provider-native image or snapshot IDs. For Hetzner, this runs directly and requires exactly one matching local native checkpoint record; it does not provide general delete-by-ID access.
Promoting a coordinator-managed AWS AMI or Azure snapshot creates a durable pin alongside each matching default, scoped catalog entry, or AWS catalog-only variant. Pins prevent both manual checkpoint deletion and opted-in automatic expiry; replacement or retirement removes only its matching pin. Generic image delete refuses a managed checkpoint image and AWS backing snapshots, so retire the relevant promotion and delete its owning checkpoint explicitly.
See the image command reference for full flags.