GARM is an open-source, self-hosted runner manager for GitHub Actions and Gitea Actions. It automatically creates, scales, and destroys ephemeral runner instances across multiple clouds and infrastructure providers from a single controller.
- Multi-cloud from a single controller -- manage runners across AWS, Azure, GCP, OpenStack, OCI, LXD, Incus, Kubernetes, and more, all from one GARM instance. Mix and match providers freely.
- GitHub.com, GitHub Enterprise Server, and Gitea -- first-class support for all three forges.
- Pools and Scale Sets -- webhook-driven pools with configurable balancing (round-robin or bin-packing), plus native GitHub Actions Runner Scale Sets.
- Scale to zero -- create on-demand pools that only spin up runners when jobs are queued.
- Pluggable provider architecture -- providers are standalone executables. Use the 10+ existing providers or write your own in any language.
- Single binary, minimal dependencies -- no external database server, no message broker. GARM ships as one binary with an embedded SQLite database.
- Built-in web UI -- manage runners, pools, credentials, and endpoints from the browser.
- Kubernetes operator -- production-grade k8s integration via the GARM operator by @mercedes-benz.
GARM supports two scaling modes:
Pools receive workflow_job webhooks from GitHub/Gitea, match jobs to pools by label, and create runners on demand. When multiple pools match, a configurable balancer (round-robin or pack) decides which pool handles the job.
Scale Sets use GitHub's native message queue. GitHub handles scheduling; GARM handles provisioning.
Important
The README and documentation in the main branch are relevant to the not yet released code that is present in main. Following the documentation from the main branch for a stable release of GARM, may lead to errors. To view the documentation for the latest stable release, please switch to the appropriate tag. For information about setting up v0.2.0-beta1, please refer to the v0.2.0-beta1 tag.
Caution
The main branch holds the latest code and is not guaranteed to be stable. If you are looking for a stable release, please check the releases page. If you plan to use the main branch, please do so on a new instance. Do not upgrade from a stable release to main.
Pick the quickstart that matches your setup:
- Quickstart: Docker -- deploy GARM as a Docker container (simplest)
- Quickstart: Systemd -- deploy GARM as a native Linux service
- First Steps -- add credentials, a repository, and your first runner pool
For Kubernetes deployments, see the GARM operator. To build from source, see Building from Source.
Full documentation lives in the doc/ directory:
| Section | Guides |
|---|---|
| Setup | Credentials · Configuration · Webhooks |
| Usage | Managing Entities · Pools and Scaling · Scale Sets |
| Advanced | Templates · Providers · Gitea · Agent and Object Store |
| Operations | Monitoring · Performance · FAQ |
If you find the documentation lacking, please open an issue. Feedback from new users is especially valuable.
GARM uses external providers to create runners in a particular IaaS. Providers are standalone executables that GARM calls to manage runner instances.
| Provider | Repository |
|---|---|
| Akamai/Linode | flatcar/garm-provider-linode (experimental) |
| Amazon EC2 | cloudbase/garm-provider-aws |
| Azure | cloudbase/garm-provider-azure |
| CloudStack | nexthop-ai/garm-provider-cloudstack |
| GCP | cloudbase/garm-provider-gcp |
| Incus | cloudbase/garm-provider-incus |
| Kubernetes | mercedes-benz/garm-provider-k8s |
| LXD | cloudbase/garm-provider-lxd |
| OpenStack | cloudbase/garm-provider-openstack |
| Oracle OCI | cloudbase/garm-provider-oci |
Follow the instructions in each provider's README to install them.
Providers are external executables that GARM calls to manage runner lifecycle in a given IaaS. They can be written in any language. See Writing an external provider for details.
Whether you're running into issues or just want to drop by and say "hi", feel free to join us on Slack.