GARM Documentation

May 17, 2026 ยท View on GitHub

GARM (GitHub Actions Runner Manager) automatically creates and manages self-hosted GitHub Actions runners across multiple infrastructure providers. It supports GitHub.com, GitHub Enterprise Server, and Gitea.

Quick start

Get GARM running and create your first runner pool:

  1. Quickstart: Docker -- Deploy GARM as a Docker container (simplest)
  2. Quickstart: Systemd -- Deploy GARM as a native Linux service
  3. First Steps -- Add credentials, a repository, and your first runner pool

Guides

GuideDescription
CredentialsPATs, GitHub Apps, Gitea tokens, and required permissions
Managing EntitiesRepositories, organizations, enterprises, endpoints, and webhooks
Pools and ScalingPool configuration, scaling behavior, balancing, labels, and runner management
Scale SetsGitHub scale sets as an alternative to webhook-driven pools
TemplatesCustomizing runner bootstrap scripts
Using GARM with GiteaGitea-specific setup and differences from GitHub
Agent Mode and Object StoreWebSocket agent mode, remote shell, file storage

Reference

PageDescription
Configuration ReferenceComplete config.toml reference
ProvidersSupported providers and configuration
Monitoring and DebuggingMetrics, log streaming, events, and the top dashboard
PerformanceCached runners, image optimization, LXD tuning
WebhooksAutomatic and manual webhook setup
Building from SourceCompiling GARM, the Web UI, and regenerating API clients
FAQCommon questions and answers

How it works

GitHub/Gitea                         GARM                        Provider (LXD, AWS, etc.)
     |                                |                                |
     |-- webhook: job queued -------->|                                |
     |                                |-- create instance ------------>|
     |                                |                                |-- boots VM/container
     |                                |<-- instance ready -------------|
     |                                |                                |
     |<-- runner registers -----------|                                |
     |                                |                                |
     |-- job runs on runner --------->|                                |
     |                                |                                |
     |-- webhook: job completed ----->|                                |
     |                                |-- delete instance ------------>|
     |                                |                                |
  1. GitHub sends a workflow_job webhook when a job is queued (or GARM polls a scale set message queue)
  2. GARM finds a matching pool and asks the provider to create an instance
  3. The instance boots, installs the runner, and registers with GitHub
  4. The runner picks up the job and executes it
  5. When the job completes, GARM deletes the instance

Key concepts

ConceptDescription
ControllerA GARM installation, identified by a unique Controller ID
EndpointA GitHub.com, GHES, or Gitea server that GARM connects to
CredentialA PAT or GitHub App tied to an endpoint, used to manage runners
EntityA repository, organization, or enterprise managed by GARM
ProviderAn external executable that creates/destroys infrastructure (LXD, AWS, etc.)
PoolA group of runners with the same config (image, flavor, labels, provider)
Scale SetAn alternative to pools using GitHub's message queue instead of webhooks
RunnerA self-hosted GitHub/Gitea runner instance
TemplateA script that customizes how runners are bootstrapped

Supported providers

ProviderRepository
Akamai/Linodeflatcar/garm-provider-linode (experimental)
Amazon EC2cloudbase/garm-provider-aws
Azurecloudbase/garm-provider-azure
CloudStacknexthop-ai/garm-provider-cloudstack
GCPcloudbase/garm-provider-gcp
Incuscloudbase/garm-provider-incus
Kubernetesmercedes-benz/garm-provider-k8s
LXDcloudbase/garm-provider-lxd
OpenStackcloudbase/garm-provider-openstack
Oracle OCIcloudbase/garm-provider-oci