awesome-runners
A curated list of awesome self-hosted GitHub Action runners in a large comparison matrix
https://github.com/jonico/awesome-runners
Last synced: 15 days ago
JSON representation
Matrix bonus
A word about self-hosted action runner images / virtual environments and how to test locally
Purpose
A word about self-hosted action runner images / virtual environments and how to test locally
- nektos/act - P option](https://github.com/nektos/act#use-an-alternative-runner-image), see a more complex example here.
- a LOT of pre-installed tools - hosted runner, this would result in images > 18 GB. In many cases where you have a better picture for which purposes/platforms you will use your self-hosted runners, this is probably not what you want for performance and maintenance reasons. All of the self-hosted solutions compared allow to define custom images with custom tooling.
General collection of self-hosted runner best practices
- dduzgun-security/github-self-hosted-runners - hosted runners by yourself.
- Harden-Runner - Runtime security monitoring and egress control for GitHub Actions runners, including self-hosted runner deployments.
- GitHub Actions secure use reference - GitHub's guidance for hardening workflows, secrets, permissions, and self-hosted runner usage.
The matrix (might be better readable on [GitHub pages](https://jonico.github.io/awesome-runners/))
A word about self-hosted action runner images / virtual environments and how to test locally
- actions/actions-runner-controller - runner-controller.svg)](https://github.com/actions/actions-runner-controller/blob/master/LICENSE) | k8s | ✅ | Enterprise, Org, Repo, Labels, RunnerGroups | k8s manifests & dynamic scaling | ✅ (pending + running jobs or percentage runners already busy, check run events, scale up/down and flapping prevention parameters) | x86, AMD64, ARM, ARM64 | ✅ | no | yes (if ephemeral option is used) | yes (install time, optional DinD) | only if github-webhook autoscaler is used | no | yes (IssueOps project available) | actions-runner controller + at least one pod per org runner |
- myoung34/docker-github-actions-runner - github-actions-runner.svg)](https://github.com/myoung34/docker-github-actions-runner/blob/master/LICENSE) | Docker | ✅ | Org, Repo, Labels, RunnerGroups | docker-compose, Nomad & k8s examples | ❌ | x86, ARM64, ARM | ✅ | yes | no | yes (DinD) | no | no | no | no |
- evryfs/github-actions-runner-operator - actions-runner-operator.svg)](https://github.com/evryfs/github-actions-runner-operator/blob/master/LICENSE.txt) | k8s | ✅ | Organization, Repo | yes (k8s manifests define max and min) |✅ scales up to min runners ASAP, then adds one runner at a time up to max if all current runners are busy, scales down idle runners up to min| x86 | ✅ | no | yes (ephemeral from v0.10.0) | yes (install time, optional DinD) | no | no | no | actions-runner controller |
- MonolithProjects/ansible-github_actions_runner - github_actions_runner.svg)](https://github.com/MonolithProjects/ansible-github_actions_runner/blob/master/LICENSE) | bare metal/VM | ✅ | Organization, Repo, Labels | based on Ansible playbook | ❌ | x86, AMD64, ARM, ARM64 | explicitly in playbook | no | no | install Ansible agents | Ansible agents | possible | no | Ansible agents |
- SanderKnape/github-runner - runner.svg)](https://github.com/SanderKnape/github-runner/blob/master/LICENSE.md) | Docker | ❌ | Org, Repo, Labels | k8s manifest example | ❌ | x86 | ✅ | yes | no | no | no | no | no | no |
- machulav/ec2-github-runner - github-runner.svg)](https://github.com/machulav/ec2-github-runner/blob/master/LICENSE) | AWS EC2 | ❌ | Repo | GitHub Actions workflow params | ✅ (1 runner per workflow run that requests it) | x86 | part of Actions workflow | no | yes (ephemeral) | no | embedded in GitHub Action workflow | possible | yes (Actions Workflow) | no |
- terraform-google-modules/terraform-google-github-actions-runners - google-modules/terraform-google-github-actions-runners.svg)](https://github.com/terraform-google-modules/terraform-google-github-actions-runners/blob/master/LICENSE) | k8s (GKE), Docker, VMs (GCE) | ❌ | Repo | Terraform config/k8s manifests | only on k8s, based on generic pod CPU consumption (HPA metric) | x86 | only worked for Docker | yes | no | no | no | VMs could be configured like this | no | at least one idle runner to allow HPA to kick in based on CPU consumption |
- github-developer/self-hosted-runners-anthos - developer/self-hosted-runners-anthos.svg)](https://github.com/github-developer/self-hosted-runners-anthos/blob/master/LICENSE) | k8s (Anthos GKE) | ❌ | Repo | Terraform config/k8s manifests | only on k8s, based on generic pod CPU consumption (HPA metric) | x86 | ✅ | yes | no | yes, for DinD (can be turned off) | no | no | no | at least one idle runner to allow HPA to kick in based on CPU consumption |
- cosmoconsult/github-runner-windows - runner-windows.svg)](https://github.com/cosmoconsult/github-runner-windows/blob/master/LICENSE) | Windows Docker container | ❌ | Org, Repo | docker compose example in blog post | ❌ | win-x86 | replace but not remove | yes | no | no | no | no | no | no |
- peter-murray/github-actions-runner-container - murray/github-actions-runner-container.svg)](https://github.com/peter-murray/github-actions-runner-container/blob/master/LICENSE) | Docker | ❌ | Enterprise, Org, Repo, Labels, RunnerGroups | ❌ | ❌ | x86 | ✅ | yes | yes | no | no | no | no | no |
- lts-beratung/ansible-github-action-runner - beratung/ansible-github-action-runner.svg)](https://github.com/lts-beratung/ansible-github-action-runner/blob/master/LICENSE.md) | bare metal or VM | ❌ | Org, Repo | Ansible playbook | ❌ | x86 | ✅ | yes | no | install Ansible agents | Ansible agents | possible | no | Ansible agents |
- rakheshster/github-runner-on-ubuntu - runner-on-ubuntu.svg)](https://github.com/rakheshster/github-runner-on-ubuntu/blob/master/LICENSE) | Azure VM (ARM template) | ❌ | Repo | ❌ | ❌ | x86 | ❌ | yes | no | no | no | possible | no | no |
- ChristopherHX/github-act-runner - act-runner.svg)](https://github.com/ChristopherHX/github-act-runner/blob/master/LICENSE) |bare metal|✅|Enterprise, Org, Repo, Labels, RunnerGroups|❌|❌|x86, AMD64, ARM, ARM64, riscv64, s390x, ppc64, ppc64le, mips, mipsle, mips64, mips64le on Linux, Windows, macOS, Openbsd, Freebsd, Netbsd, Solaris, Dragonfly, Plan9, Android and Illumos|❌|no|yes|no|no|no|no|no|
- related-sciences/gce-github-runner - sciences/gce-github-runner.svg)](https://github.com/related-sciences/gce-github-runner/blob/main/LICENSE) | GCP GCE | ❌ | Repo | GitHub Actions workflow params | ✅ (1 runner per workflow run that requests it) | x86 | part of Actions workflow | no | yes (ephemeral) | no | embedded in GitHub Action workflow | possible | yes (Actions Workflow) | no |
- whywaita/myshoes - closed](https://img.shields.io/github/issues-closed/whywaita/myshoes.svg)](https://github.com/whywaita/myshoes/issues?q=is%3Aissue+is%3Aclosed) | Virtual Machine: LXD, OpenStack, AWS, and more! (pluggable, can implement any platform) The already implemented provider is whywaita/myshoes-providers | ✅ | Repo, Org | GitHub Actions workflow params | ✅ (1 runner per workflow run that requests it) | any platform that can start bash script or transpiled script from a bash script | part of Actions workflow | no | yes (ephemeral) | no | yes (GitHub check_run events) | possible (provide image in some provider, e.g. whywaita/virtual-environments-lxd and shoes-lxd) | no | myshoes daemon process |
- boozallen/goobernetes - closed](https://img.shields.io/github/issues-closed/boozallen/goobernetes.svg)](https://GitHub.com/boozallen/goobernetes/issues?q=is%3Aissue+is%3Aclosed) | k8s | ✅ | Enterprise, Org, Repo, Labels, RunnerGroups | k8s manifests & dynamic scaling | ✅ (pending + running jobs or percentage runners already busy, check run events, scale up/down and flapping prevention parameters) | AMD64, others possible | ✅ | no | yes (if ephemeral option is used) | yes (install time, optional DInD) | only if github-webhook autoscaler is used | no | yes (IssueOps project available) | actions-runner controller + at least one pod per org runner |
- some-natalie/kubernoodles - natalie/kubernoodles.svg)](https://github.com/some-natalie/kubernoodles/blob/main/LICENSE) | k8s | ✅ | Enterprise, Org, Repo, Labels, RunnerGroups | k8s manifests & dynamic scaling | ✅ (pending + running jobs or percentage runners already busy, check run events, scale up/down and flapping prevention parameters) | AMD64, others possible | ✅ | no | yes (if ephemeral option is used) | yes (install time, optional DinD) | only if github-webhook autoscaler is used | no | yes (IssueOps project available) | actions-runner controller + at least one pod per org runner |
- knatnetwork/github-runner - runner.svg)](https://github.com/knatnetwork/github-runner/blob/master/LICENSE.md) | Docker for single machine quick start or K8s deployments for multiple replicas | ❌ | Org, Repo, Labels | docker-compose or k8s deployment | ❌ | AMD64, ARM64 | ✅ | no | yes (if ephemeral option is used) | yes (install time, optional DinD) | no | no | no | no |
- CloudSnorkel/cdk-github-runners - github-runners.svg)](https://github.com/CloudSnorkel/cdk-github-runners/blob/main/LICENSE) | Docker on AWS CodeBuild, Fargate or Lambda | ✅ | Labels | On-demand | ✅ | AMD64, ARM64 | ✅ | no | yes (always ephemeral) | yes | yes (Lambda URL with secret) | possible | no | no |
- vbem/multi-runners - runners.svg)](https://github.com/vbem/multi-runners/blob/main/LICENSE) | bare metal/VM | ✅ | Org, Repo, Labels, RunnerGroups | CLI control | ❌ | x86, AMD64, ARM, ARM64 | CLI control | yes | no | yes | no | possible | yes (CLI) | no |
- runs-on/runs-on - on/runs-on.svg)](https://github.com/runs-on/runs-on/blob/master/LICENSE) | AWS EC2 | ✅ | Repo, Dynamic Labels | On-demand | ✅ | x86, AMD64, ARM64 | ✅ | No PAT, only JIT token | Auto-cleanup | No runtime privilege | GitHub App exposed | AllInOne and custom images possible | yes (Actions Workflow) | $15/month |
- cloudbase/garm - closed](https://img.shields.io/github/issues-closed/cloudbase/garm.svg)](https://GitHub.com/cloudbase/garm/issues?q=is%3Aissue+is%3Aclosed)|k8s,VM,Bare Metal (pluggable), available providers: k8s, EC2, OpenStack, OCI, GCP, LXD, Incus, Equinix Metal, Azure.|✅|Enterprise, Org, Repo, Labels, RunnerGroups|On-demand|✅ Scales based on workflow jobs, allows setting min/max runners per pool, scales up to "min" immediately, maintains "min" idle runners as long as "max" is not reached|x86, AMD64, ARM, ARM64|✅|no|yes (all runners are ephemeral and automatically disposed from the provider once removed from GitHub)|no (GARM can run as a non privileged user)|yes, required for github-webhook endpoint, needed for auto scaling|yes (if used as standalone, optionally it can be integrated in k8s using the garm-operator)|yes, GARM has pools which can be created in any number on any entity (org, repo, enterprise), with any runner group and with any labels|the cost of running a single container or VM with GARM, and any idle runners configured in the pools, cost depends on provider used (EC2, Azure, etc)|
- Privatehive/gcp-hosted-github-runner - hosted-github-runner.svg)](https://github.com/Privatehive/gcp-hosted-github-runner/blob/master/LICENSE) | GCP GCE | ✅ | Enterprise, Org, Repo, Labels, RunnerGroups | On-demand | ✅ 1 runner per workflow job. Created when job is "queued". Deleted when job is "completed". | x86, AMD64, ARM64 | ✅ | No PAT, only JIT token | yes (always ephemeral) | no | yes, required for github-webhook endpoint, needed for auto scaling | possible | no | no (covered by GCP free tier) |
- github-aws-runners/terraform-aws-github-runner - aws-runners/terraform-aws-github-runner.svg)](https://github.com/github-aws-runners/terraform-aws-github-runner/blob/main/LICENSE.md) | AWS EC2/Lambda for Linux, Windows and macOS VMs | ✅ | Org, Repo, Labels, Dynamic Labels, RunnerGroups | Terraform config & dynamic scaling | ✅ (pending jobs in org/repo, scale up/down and flapping prevention parameters) | x86, AMD64, ARM, ARM64, macOS (EC2, requires a dedicated host) | ✅ | no | yes (if ephemeral option is used) | no | yes (GitHub check_run events) | yes (at least intended this way) | yes (IssueOps project available) | no (only Lambdas, KMS, queue service, API gateway) |
- sprinters-sh/sprinters - sh/sprinters.svg)](https://github.com/sprinters-sh/sprinters/blob/master/LICENSE) | AWS EC2 | ❌ | Repo, Dynamic Labels | On-demand | ✅ | AMD64, ARM64 | ✅ | No PAT, only JIT token | Ephemeral instances with auto-cleanup | No privileges needed | Not exposed | Full and minimal images | Yes | $0 |
- cisco-open/forge - open/forge.svg)](https://github.com/cisco-open/forge/blob/main/LICENSE) Multi-tenant wrapper around ARC & terraform-aws-github-runner, adding automation & extra features on top with a single interface to deploy & manage | k8s (ARC) & AWS EC2/Lambda for Linux and Windows VMs (terraform-aws-github-runner) | ✅ | Org (multiple GitHub Apps per org scoped to selected repos, or one App for all repos in the org), Dynamic Labels (EC2), RunnerGroups | k8s manifests (ARC) & Terraform config (terraform-aws-github-runner), dynamic scaling | ✅ (ARC: pending + running jobs or percentage runners already busy, check run events, scale up/down and flapping prevention parameters; terraform-aws-github-runner: pending jobs in org/repo, scale up/down and flapping prevention parameters) | x86, AMD64, ARM, ARM64, macOS (EC2 lane, requires a dedicated host) | ✅ | no | yes (if ephemeral option is used) | yes for ARC (install time, optional DinD), no for terraform-aws-github-runner | only if github-webhook autoscaler is used (ARC), no for terraform-aws-github-runner | yes (merges ARC & terraform-aws-github-runner features) | yes (IssueOps project available) | EKS cluster + ARC controller + at least one pod per org runner (ARC); no, only Lambdas, KMS, queue service, API gateway (terraform-aws-github-runner) |
-
Flinner/gh-runnerctl
- runnerctl.svg)](https://github.com/Flinner/gh-runnerctl/blob/main/LICENSE) | bare metal/VM, local or over ssh — no root, no Docker (user-level systemd or detached supervisor; targets HPC login nodes and shared hosts) | ❌ | Org, Repo, Labels, RunnerGroups | declarative
runners.toml(countper pool), converged byup/reload; crashed runners restarted with backoff | ❌ (fixed-size pools by design) | x64, ARM64 (Linux) | busy-aware CLI/converge (upprunes,rmderegisters; skips busy runners unless--force) | no (token never leaves the control machine; remotes get short-lived registration tokens over ssh stdin) | no (persistent runners) | no (never root; no sudo at any step) | no | no | no | one user-level supervisor process per machine | - Manzanita - hosted) | managed macOS VM (Apple Silicon M4 Pro) | ❌ | Org, Repo, Labels (via GitHub App) | managed by provider (buy N concurrent runners) | managed (jobs dispatched to purchased concurrency) | macOS (Apple Silicon, M4 Pro) | ✅ (ephemeral, one job per VM) | no (GitHub App) | yes (fresh VM per job) | n/a (fully managed) | no | yes (Xcode + toolchain preinstalled) | yes (dashboard + GitHub App) | none (flat monthly price, no infra to idle) |
- eyupio/zoomies - closed](https://img.shields.io/github/issues-closed/eyupio/zoomies.svg)](https://github.com/eyupio/zoomies/issues?q=is%3Aissue+is%3Aclosed) | Docker, Podman, bare process; no Kubernetes required | configurable API endpoint; untested | Org, Repo, Labels | UI, CLI and YAML; per-pool limits across existing hosts | ✅ (queued jobs via workflow_job webhooks; polling fallback; min/max runners) | Linux AMD64, ARM64; Windows AMD64 process agent builds, runtime unqualified; macOS controller for development | ✅ (ephemeral registration and cleanup reconciliation) | no (GitHub App; single-use JIT config for ephemeral runners) | yes (ephemeral containers by default; process runners do not reset the host) | rootless Docker/Podman supported; optional DinD uses a privileged sidecar | controller webhook optional with polling fallback; agents connect outbound | no (customisable runner images) | yes (web UI and CLI for pools) | controller + existing agent hosts; zero idle runners possible, host costs remain |
- Gondola - lived JIT runner configuration | One job per EC2 instance; instance and root-volume termination | AWS deployment permissions; Docker socket gives a job control of its host | No inbound GitHub webhook; outbound long polling | Lean/development image profiles; custom AMIs and runner containers | Fleet setup through Terraform/OpenTofu; workflows select approved labels | Controller tasks, coordination and network services; subscription for paid plans; zero idle EC2 runners possible |
- CRACI - hosted) | managed Linux VMs, one isolated VM per job | ❌ | Org, Repo (via GitHub App, all or selected repositories) | managed by provider; runner size 1 to 32 vCPU per job | managed | Linux x86-64, ARM64 | ✅ (one VM per job) | no (GitHub App) | yes (VM discarded after the job) | n/a (fully managed) | no | yes (GitHub-compatible Ubuntu 24.04 image; Docker Engine, Buildx, Compose) | yes (dashboard + GitHub App) | monthly plan fee; build minutes billed per second |
- redhat-actions/self-hosted-runner-installer - actions/self-hosted-runner-installer.svg)](https://github.com/redhat-actions/self-hosted-runner-installer/blob/master/LICENSE) | Kubernetes (OpenShift) | ✅ | Org, Repo, Labels | HELM chart parameters | ❌ | x86 | ✅ | yes | no | no | no | no | no | no |
- Sengi - hosted) | managed Linux VMs on bare metal (AMD Ryzen 9 7950X3D), one fresh VM per job | ❌ | Repo, Labels (via GitHub App on an org or personal account, all or selected repositories) | managed by provider; 2, 4 or 8 vCPU per job, chosen by label | ✅ (one VM per queued job) | Linux x86-64 (Ubuntu 24.04) | ✅ (ephemeral, one job per VM) | no (GitHub App; single-use JIT config) | yes (VM destroyed after the job) | n/a (fully managed) | no | yes (GitHub-compatible Ubuntu 24.04 image; Docker, Compose, Buildx) | yes (dashboard + GitHub App) | none (billed per job-minute, no infrastructure to idle) |
-
Avrea
- hosted) | managed ephemeral VMs on dedicated hardware, one VM per job | ❌ | Org, Repo (via GitHub App, all or selected repositories) | managed by provider; 1 to 32 vCPU per job, chosen by label | ✅ (one VM per queued job; concurrency caps grow with usage) | Linux x86-64, Linux ARM64, macOS (Apple Silicon), Windows | ✅ (ephemeral, one job per VM) | no (GitHub App; just-in-time runner registration) | yes (VM discarded after the job) | n/a (fully managed) | no | yes (GitHub-compatible images: Ubuntu 22.04/24.04/26.04, macOS 26, Windows 2025; plus colocated build and package cache adapters) | yes (console + GitHub App; labels like
avrea-ubuntu-latest-4-vcpu) | none (pay as you go, metered per second at per-minute rates; 3,000 free minutes per month) |