Actions Runner Controller
Run self-hosted GitHub Actions runners on Kubernetes
Actions Runner Controller manages self-hosted GitHub Actions runners as scalable workloads on Kubernetes, creating and destroying runners on demand. It gives teams elastic, self-hosted CI capacity.
Key features
- Autoscaling runners
- Kubernetes-native
- Ephemeral runner pods
- Webhook-driven scaling
Pros & cons
Strengths
- Elastic CI capacity
- Keeps builds in your cluster
Trade-offs
- Kubernetes expertise required
- Complex configuration
Actions Runner Controller replaces
Last reviewed Sep 13, 2026 · 884 words
GitHub-hosted Linux runners cost about $0.008 per minute on private repositories at last check, after the free allowance, and a team with 30 minutes of CI per push burns through that faster than anyone budgets. Actions Runner Controller (ARC) puts those runners on a Kubernetes cluster you already pay for, scales them from 0 to whatever the queue needs, and destroys each pod after one job. It is the officially maintained way to do this, it works, and it is more machinery than most small teams need. Below is what the install looks like, where it hurts, and the two cheaper options I would try first.
Two modes, and only one is worth learning
ARC has a legacy mode (RunnerDeployment resources, cert-manager, a webhook or polling-based autoscaler) and the newer runner scale set mode, which GitHub adopted when it took over maintenance. The scale set mode uses a long-lived listener that holds a connection to GitHub's job queue and asks the controller for pods as jobs arrive, so scaling is driven by demand rather than polling. It needs no cert-manager and no webhook. Every new install should use it; the legacy documentation still ranks well in search and will lead you astray. The whole thing is 2 Helm charts:
helm install arc \
--namespace arc-systems --create-namespace \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
helm install arc-runner-set \
--namespace arc-runners --create-namespace \
--set githubConfigUrl="https://github.com/your-org" \
--set githubConfigSecret.github_token="ghp_..." \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
The release name of the second chart, arc-runner-set, becomes the label your workflows target with runs-on: arc-runner-set. Use a GitHub App rather than a personal token for anything beyond a trial; the App's credentials go in the same secret with github_app_id, github_app_installation_id and github_app_private_key. The controller itself idles in a couple hundred megabytes; the 512 MB figure covers controller plus listener, not the runner pods, which are sized per job.
The Docker-in-Docker decision
The default runner pod cannot build container images, because it has no Docker daemon. You pick one of 2 container modes. containerMode.type=dind adds a privileged sidecar running dockerd, which gives you docker build exactly as on a GitHub-hosted runner and makes your security team unhappy, because a privileged pod on a shared cluster is a node escape waiting for a CVE. containerMode.type=kubernetes runs each job step in its own pod through the runner container hooks, which avoids privilege but breaks any action that assumes a local Docker socket, and needs a ReadWriteMany volume for the workspace. Most teams choose dind on a dedicated node pool with a taint, which is the pragmatic answer, and a dedicated node pool means the cost saving is smaller than the headline.
Where it hurts in practice
Caching. Every pod is fresh, so actions/cache round-trips to GitHub's cache service over the internet, and a 2 GB Docker layer cache pulls every job. You end up running a registry mirror and a persistent cache volume anyway. Image pulls: the runner image is over 1 GB and each scale-up on a new node pays for it. Public repositories: GitHub's own guidance is not to use self-hosted runners on public repos, because a pull request from a stranger runs code on your cluster. Debugging: a failed job's pod is gone before you can kubectl exec into it, so logs and artefacts have to go out during the run. None of these are blockers; all of them are afternoons.
The cheaper options to try first
| Your situation | Do this |
|---|---|
| Under about 3,000 CI minutes a month | Stay on GitHub-hosted runners |
| One team, steady load, no Kubernetes | A single VM with the runner installed as a service |
| Kubernetes already in production, bursty load | ARC in scale set mode |
| You want CI off GitHub entirely | Forgejo or Gitea Actions with their own runner |
The single-VM runner is underrated. A 4-core VM running the runner binary as a systemd service, with Docker installed and a cron to prune images, handles a small team's CI with persistent caches and no orchestration. It does not scale to zero and it does not isolate jobs, and for one team on private repos both are acceptable. If your objection to GitHub-hosted runners is GitHub rather than the price, the CI/CD category has the full set of self-hosted forges and runners, and Forgejo's runner speaks the same workflow syntax closely enough that most actions port unchanged.
What I'd do
If you already run Kubernetes for real workloads and your Actions bill has 4 digits, install ARC in scale set mode with a GitHub App, dind on a tainted node pool, a registry mirror in-cluster, and a minimum of 0 runners so idle costs nothing. If you do not already run Kubernetes, do not adopt it for CI; put the runner on a VM and spend the saved week on tests. And if the goal is independence from GitHub, ARC is the wrong project: it makes GitHub cheaper, not optional.
Similar automation & workflows apps
n8n
Automation & WorkflowsWorkflow automation with a node-based editor
Replaces Zapier, Make
Firecrawl
Automation & WorkflowsTurn websites into clean data for AI applications
Replaces Apify
Crawl4AI
Automation & WorkflowsOpen-source web crawler built for LLM data pipelines
Replaces Firecrawl
Huginn
Automation & WorkflowsAgents that monitor and act on your behalf
Replaces IFTTT, Zapier
Apache Airflow
Automation & WorkflowsProgrammatically author, schedule and monitor workflows
Replaces AWS Step Functions, Azure Data Factory
ToolJet
Automation & WorkflowsLow-code platform for building and automating business tools
Replaces Retool, Microsoft Power Apps