Skip to main content
On a stock image, every job spends its first minute or two the same way: downloading actions/runner, installing its dependencies, then installing whatever your build needs. An image of your own does that work once. It is the single biggest cold-start win available, and on a private network it removes the package-mirror traffic from every job entirely.

What the boot script looks for

Airship does not require anything of your image. It prefers a few things, and falls back to doing them itself.
the runner, extracted
If /opt/actions-runner/.version contains exactly the runner version Airship asked for, that installation is used as-is and nothing is downloaded. Anything else — a missing file, a different version — and the directory is replaced with a fresh download.
created if absent
Airship creates a runner user with a home directory, passwordless sudo, and membership of the docker group if one exists. Creating it yourself is fine; Airship leaves an existing one alone.
installed if absent and gpu: is set
If nvidia-smi is already on the image, the driver install is skipped entirely. Baking it is worth minutes per GPU job.
required on a minimal image
A very stripped-down image without them cannot fetch the runner. This is the usual cause of “the instance launched but no runner appeared”.
Pin the runner version you bake, and keep it current. GitHub stops sending jobs to runners more than 30 days behind a release — a stale baked runner is replaced at boot (so jobs keep working, slowly) until it falls so far behind that GitHub refuses it.

What else is worth baking

Your language toolchains

The exact compilers, SDKs and package managers your build needs, at the versions it needs, rather than a setup-* action per job.

Base container images

docker pull of your base layers at image-build time means no registry round trip per job.

A warm dependency cache

A populated ~/.cargo, ~/.m2 or npm cache gives even a cache miss a head start.

Your CA certificates and config

Internal registries, proxies and certificate bundles, already trusted.

Building one

Launch an instance from the base AMI, provision it, then create an image from it. The result is an AMI ID, specific to that region:
airship.yaml
Keep one definition per region, or copy the AMI and use a fallback list of image and region together.
Build the image in CI, on an Airship runner. A nightly workflow that provisions a machine, snapshots it and publishes to a family or gallery keeps images current without anyone remembering to do it.

Keeping definitions stable

Pointing at a moving target — a Google Cloud image family, or an Azure gallery image without a pinned version — means airship.yaml never has to change when you rebuild. On AWS, where the image is an ID, the equivalent is to publish the new AMI ID through a small automated pull request.

Marketplace and vendor images

Any image your credential can launch works, including vendor images with drivers and SDKs already installed — a deep-learning image is often faster to adopt than building your own GPU image.
A marketplace image usually needs its terms accepted for your account or subscription before it will launch. Until then every launch fails permanently, with the provider’s own message on Events. See Machine images.

Together with everything else

The three compose: an idle pool of machines booting your own image, with cache acceleration on, is as close to instant as a fresh machine per job gets.