Does BYOC Support Custom VM Images?

Yes. WarpBuild BYOC runs your own VM images on AWS, GCP, and Azure once they meet the documented requirements, and a custom runner selects the image.

Answer

Yes. WarpBuild BYOC accepts VM images you build in your own cloud account, provided the image meets the requirements in the custom VM images documentation, and you register the image with WarpBuild so a custom runner definition can select it. The image then runs on instances inside your account, and workflows reach it through the Runner ID of that custom runner, which is the runner name prefixed with warp-custom-.

Two things narrow the answer. The images in question are VM images, which the docs call out as distinct from custom container image support. And the capability belongs to BYOC, so it does not apply to WarpBuild hosted capacity, where you select from the maintained catalog instead.

BYOC runs on AWS, GCP, and Azure, and the feature matrix marks custom VM images as supported on all three, checked on 2026-08-13.

Where the runner runsCustom VM images
WarpBuild hosted capacityNot applicable
BYOC on AWSSupported
BYOC on GCPSupported
BYOC on AzureSupported

One caveat sits under that row. The documented requirement list is written for AMIs, Linux and Windows, so read the custom VM images documentation against your own cloud before assuming the same package list transfers to a GCP or Azure image.

There is no additional cost for using custom VM images.

Detail

What the image has to carry

The Linux distro underneath the image has to use systemd, because WarpBuild relies on it to run the WarpBuild agent. Ubuntu and Amazon Linux 2023 both qualify. On top of that, five packages must be present.

PackageWhy the runner needs it
curlAgent and artifact downloads
wgetAgent and artifact downloads
bashSetup and hook script execution
jqRunner orchestration
libicu.NET runtime dependency of the GitHub Actions runner

Five more come with every supported distro and must survive your hardening pass: tar, gzip, coreutils (which provides id, chpasswd, chown, tr, and sed), shadow-utils (which provides useradd and usermod), and systemd. The package name for libicu moves between distro versions, so resolve it against your own base rather than copying a name across images.

Windows images add three conditions. aria2 has to be installed and reachable through the system PATH, because WarpBuild uses it in place of the slower default Windows download path. On AWS, the EC2 instance has to be sysprepped before you turn it into an image, either through the EC2Launch settings dialog or through the Packer sysprep commands. And jobs run under the runneradmin user, the same account GitHub's Windows runners use, so user-scoped environment variables set under a different login are invisible to the job and belong at machine level instead.

If your image needs to run something around each job, use the WARPBUILD_ACTIONS_RUNNER_HOOK_JOB_STARTED and WARPBUILD_ACTIONS_RUNNER_HOOK_JOB_COMPLETED variables. WarpBuild already consumes GitHub's own hook variables to orchestrate runners for your jobs, so the unprefixed names have no effect.

Build the image, then register it

A Packer template keeps the image reviewable and reproducible. The shape below starts from an Ubuntu 24.04 base, creates the runner user, and prepares the tool cache directories.

locals {
  version = "1.0.0"
}

source "amazon-ebs" "ci-base" {
  region        = "us-east-1"
  instance_type = "t3.micro"
  ami_name      = "ci-base-v${local.version}"

  source_ami_filter {
    filters = {
      name             = "ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.*-amd64-server-*"
      root-device-type = "ebs"
    }
    owners      = ["099720109477"]
    most_recent = true
  }

  ssh_username = "ubuntu"
}

build {
  sources = ["source.amazon-ebs.ci-base"]

  provisioner "shell" {
    inline = [
      "sudo groupadd runner || true",
      "sudo useradd -m -g runner -s /bin/bash runner || true",
      "sudo apt-get update",
      "sudo apt-get install -y curl wget jq unzip git libicu-dev",
      "sudo mkdir -p /opt/hostedtoolcache",
      "sudo chown -R runner:runner /opt/hostedtoolcache",
    ]
  }
}

Registration is four steps, documented on the custom VM images page.

  1. Set up a WarpBuild Stack, which fixes the region, network, and object storage the runners use (BYOC documentation).
  2. Open the custom images page in the dashboard and press Add Image. Every image in the region your stack lives in is listed, so an image built in another region will not appear.
  3. Create a custom runner that uses the image, along with the instance types, disk settings, and IP configuration for that runner.
  4. Reference the Runner ID in runs-on.
.github/workflows/ci.yml
jobs:
  build:
    runs-on: warp-custom-ci-base-4x
    steps:
      - uses: actions/checkout@v4
      - run: make build
      - run: make test

The install steps the image now covers come out of the workflow in the same pull request. The AWS click path, including the stack and connection work that has to exist first, is on the AWS BYOC page, and the AMI specifics are in custom AMIs for BYOC runners on AWS.

When baking beats installing at job time

The fee side of this decision is small, so measure it in per-job seconds and then weigh the maintenance.

At 3,000 workflow jobs per month, every second of install time removed from a job returns 50 minutes of runner time per month. The table applies that at four levels, using the BYOC Linux fee of $0.002 per minute and the hosted warp-ubuntu-latest-x64-4x rate of $0.008 per minute (pricing page, checked on 2026-08-13).

Seconds removed per jobRunner minutes per monthFee returned at $0.002Fee returned at $0.008Build wait returned
15750$1.50$6.0012.5 hours
452,250$4.50$18.0037.5 hours
904,500$9.00$36.0075 hours
24012,000$24.00$96.00200 hours

The image pipeline costs almost nothing to run. A 12 minute image build on warp-ubuntu-latest-x64-4x at $0.008 per minute is $0.096 per rebuild, about $0.42 per month at a weekly rebuild. Against the 15 second row, the fee math already clears by a wide margin.

What decides the question is upkeep. The pipeline needs an owner, a version scheme, a rebuild trigger when the base image picks up security updates, and a rollback path when a bad image reaches production runners. Because of that, teams usually set the bar above the fee break-even: bake when the installs you would remove run longer than about 90 seconds per job, or when the install step is a recurring source of red builds whatever its length.

Two situations argue the other way. If the tooling already ships in the maintained runner images, changing the label is the cheaper move, since. With tooling kept current for you. And if the slow part is machine start rather than tool install, a fatter image makes it worse; standby disks are the lever there.

Can I use a custom VM image on WarpBuild hosted runners?

No. Custom VM images are a BYOC capability, so the image runs on instances in your own cloud account under a custom runner you configure. On hosted capacity you pick from the maintained catalog, which covers Linux x64, Linux ARM64, macOS, and Windows runners. The runner image definition covers the difference between a maintained image and one you bake yourself, and BYOC runners on AWS covers the account setup a custom image needs.

Does a custom VM image cost extra?

No. There is no additional cost for using custom VM images (custom VM images documentation). You pay the BYOC runner fee of $0.002 per minute and your own cloud account bills the instance, disk, and data transfer at your rates.

What happens if the image is missing a required package?

The runner starts and then fails on the first job it takes. WarpBuild relies on systemd to run its agent, and the GitHub Actions runner needs libicu as a .NET runtime dependency, so a hardened base that strips either one produces a machine that looks healthy until a job lands on it. Validate the package list during the image build rather than on the first workflow run. Building custom runner images for GitHub Actions walks through the full requirement list and the hook variables that go with it.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.