GitHub has just announced the availability of custom images for its hosted runners. They've finally left the public preview phase that started back in October behind them. This feature will enable teams to use a GitHub-approved base image and then construct a virtual machine image that really meets their workflow requirements.
The premise is straightforward, and the problem it solves is familiar to anyone who has managed CI at scale. Every time a workflow runs on a standard GitHub-hosted runner, it installs tooling from scratch. Node, Python runtimes, language-specific SDKs, internal certificates, custom binaries, all of it downloaded again, every run, every job. Custom images flip that model: you bake everything in one go, and later jobs bypass the setup completely.
The process has three steps: set up an image-generation runner, run a workflow with the snapshot keyword, then create a runner that uses that image. The snapshot keyword is the core mechanism. Each job with the keyword creates a separate image. Every successful run produces a new version; GitHub automatically increments the minor version number. Teams that want tighter control can pin to a specific major version using the mapping syntax, and runners can be configured to use the latest or locked to a specific version number. A runner pinned to the latest will pick up the new image automatically the next time a new version is generated; one pinned to a specific version stays put until someone manually updates it.
GitHub suggests setting up image generation as a weekly task. This helps keep dependencies up to date and ensures security patches are applied regularly. That's sensible advice, but it also means custom images are another artifact to manage; they need to be generated, versioned, and potentially audited. Governance gets a nod in the documentation: enterprise owners can manage access to custom images and set retention policies in the Actions policy settings.
The feature is exclusively available on larger runners, which means it is tied to the GitHub Team or GitHub Enterprise Cloud plans. Organizations on the free tier cannot use it. The platform of the image-generation runner must match the platform of the image being built: Linux x64, Linux ARM64, or Windows x64.
It's important to clarify what this feature isn't. It isn’t a general-purpose VM image pipeline. You can’t bring in any arbitrary AMI or GCP machine image from outside. The foundation is either a GitHub-curated base or a clean OS from GitHub. The image remains within the GitHub ecosystem. You can locate it in the organization's Actions settings under "Custom images," rather than in your own container registry. Teams hoping to reuse images across CI providers or build images outside GitHub Actions workflows will need to manage that separately.
The issue of pre-warmed, customizable execution environments isn’t new. Different CI platforms have tackled it in various ways.
GitLab CI lets teams specify any container image in .gitlab-ci.yml. This means they can easily point a job to an image in their registry, whether it's GitLab’s or an external one. There's no extra step needed for provisioning. The image is pulled at job start. GitLab Runner offers several executor types for VM-level execution, such as Docker, Kubernetes, and shell. This gives teams options for scaling compute. The runner configuration in config.toml manages pull policy, registry credentials, and caching behaviour. GitLab's model is more permissive about the image source but puts more of the image lifecycle management responsibility on the team.
CircleCI takes a two-track approach. Teams can run on machine executors with full system access, or bring their Docker images to meet specific requirements. Custom Docker images work naturally with CircleCI's container runner, where you define and publish the image yourself and reference it in the job configuration. The container runner takes containerized jobs, schedules them in a temporary pod, and runs the tasks in a container environment. It supports both CircleCI convenience images and custom Docker images. Custom VM-level images for the machine executor on CircleCI's cloud, like pre-baked AMIs, have long been requested. Users have noted that GitLab has provided similar support for some time now. CircleCI's answer for teams that need full OS-level control has mostly been self-hosted runners.
GitHub's approach to custom images is similar to using a self-hosted runner pool with pre-baked AMIs on AWS or a Packer-managed image library. However, it is fully managed and integrated into the platform. The tradeoff is the same one you get with any managed solution: less flexibility in exchange for less operational overhead. The value of that tradeoff depends on the complexity of your build environment. It also depends on whether your organization is ready to treat runner images as important artifacts. These need their own versioning and update schedules.