quickstart →

Linux runners

Native x64 and arm64 Linux runners on any EC2 instance, from Flex labels or Fleet runner definitions.

RunsOn supports both native x64 and arm64 Linux runners.

Flex

Pick a predefined runner from the runs-on label — 2cpu-linux-x64 for x64, 2cpu-linux-arm64 for arm64:

.github/workflows/ci.yml
jobs:
build:
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64
steps:
- uses: runs-on/action@v2
- run: echo "Hello from x64!"
.github/workflows/ci.yml
jobs:
build:
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-arm64
steps:
- uses: runs-on/action@v2
- run: echo "Hello from arm64!"

Most users go beyond the predefined names and tailor CPU, memory, family, and volume with job labels or custom runners.

Fleet

Define the runner shape in Terraform, publish it as a fleet, then target the fleet from workflow YAML:

main.tf
runners = {
linux-small = {
family = ["c8i.large"]
image = "ubuntu24-full-x64"
}
}
fleets = {
linux-small = {
runner = "linux-small"
}
}
.github/workflows/ci.yml
jobs:
build:
runs-on: runs-on/fleet=linux-small/env=production

Default runners#

Flex has these predefined runners. Pass one as runner=<name>, and override any part of it with other labels, for example runner=4cpu-linux-x64/family=c8. All of them use Spot instances by default (spot=false for on-demand).

RunnervCPUsMemory (GiB)Instance familiesImage
1cpu-linux-x641 or 24c8, m8a, t8iubuntu24-full-x64
2cpu-linux-x642anym8, r8ubuntu24-full-x64
4cpu-linux-x644anym8, r8ubuntu24-full-x64
8cpu-linux-x648anyc8, m8ubuntu24-full-x64
16cpu-linux-x6416anyc8, m8ubuntu24-full-x64
32cpu-linux-x6432anyc8, m8ubuntu24-full-x64
48cpu-linux-x6448anyc8, m8ubuntu24-full-x64
64cpu-linux-x6464anyc8, m8ubuntu24-full-x64
1cpu-linux-arm641 or 22 to 8m8g, m9g, t4gubuntu24-full-arm64
2cpu-linux-arm6424 to 16m8g, m9g, r8g, r9g, t4gubuntu24-full-arm64
4cpu-linux-arm644anyc8g, c9g, m8g, m9gubuntu24-full-arm64
8cpu-linux-arm648anyc8g, c9g, m8g, m9gubuntu24-full-arm64
16cpu-linux-arm6416anyc8g, c9g, m8g, m9gubuntu24-full-arm64
32cpu-linux-arm6432anyc8g, c9g, m8g, m9gubuntu24-full-arm64
48cpu-linux-arm6448anyc8g, c9g, m8g, m9gubuntu24-full-arm64
64cpu-linux-arm6464anyc8g, c9g, m8g, m9gubuntu24-full-arm64

Without a runner label, Flex uses 2cpu-linux-x64. To change a default runner or add your own, see custom runners.

Default images#

Opt into a specific image with the image label. When you set image, make sure your family uses instance types matching the image architecture (e.g. family=c8g+m8g for arm64).

ImageArchitectureDescription
ubuntu22-full-x64x64Compatible with the official Ubuntu 22.04 GitHub runner image.
ubuntu24-full-x64x64Compatible with the official Ubuntu 24.04 GitHub runner image.
ubuntu26-full-x64x64Compatible with the official Ubuntu 26.04 GitHub runner image.
ubuntu22-full-arm64arm64Compatible with the official Ubuntu 22.04 GitHub runner image.
ubuntu24-full-arm64arm64Compatible with the official Ubuntu 24.04 GitHub runner image.
ubuntu26-full-arm64arm64Compatible with the official Ubuntu 26.04 GitHub runner image.

Minimal images#

Since v3.0.7, RunsOn also publishes minimal images, for the fastest boot times. They ship the GitHub Actions runner, Docker (with Buildx and Compose), Git and Python 3, and none of the toolchains of the full images: no Node.js, Java, browsers or cloud CLIs. Use them for jobs that run in containers, or that install what they need with setup-* actions.

Like the full images, they ship libicu, which .NET needs for cultures such as en-US, and a /usr/share/dotnet that the runner user can write to, so actions/setup-dotnet works with its default install directory.

ImageArchitectureDescription
ubuntu24-minimal-x64x64Ubuntu 24.04 with the GitHub Actions runner, Docker, Git and Python 3.
ubuntu24-minimal-arm64arm64Ubuntu 24.04 with the GitHub Actions runner, Docker, Git and Python 3.
Flex
.github/workflows/ci.yml
jobs:
build:
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64/image=ubuntu24-minimal-x64
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
- run: npm ci && npm test
Fleet
main.tf
runners = {
linux-minimal = {
family = ["c8i.large"]
image = "ubuntu24-minimal-x64"
}
}

Minimal images are rebuilt on the same schedule as the full images, from the same repository ↗.

Examples#

Disable spot pricing for critical jobs:

.github/workflows/ci.yml
jobs:
build:
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64/spot=false

Only allow 4-CPU instances from compute-optimized families:

.github/workflows/ci.yml
jobs:
build:
runs-on: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c8

Fully custom definition — launched in a private subnet with a static egress IP:

.github/workflows/ci.yml
jobs:
build:
runs-on: runs-on=${{ github.run_id }}/ram=8/family=m8+c8+r8/image=ubuntu24-full-x64/spot=false/ssh=false/private=true

Need help choosing? Use the instance finder ↗ to match AWS instances to your CPU, RAM, and architecture requirements.

Quotas#

New AWS accounts have low default quotas for standard instances, so you may need an increase to launch many jobs.

How to request an increase
  1. Search for “Quotas” in the AWS console.
  2. Click “Request quota increase”.
  3. Select “EC2” as the service.
  4. Select the standard instance type.
  5. Fill in the form and submit (you request vCPUs, not instance count).
  6. Repeat for both spot and on-demand quotas.
Quota increase