selfhost.directory

The index of self-hostable projects — ranked, categorized and served with live updates.
Own your data and stop giving it to big tech.

GitHub
garm logo

Self-host garm

v0.2.1

Multi-cloud GitHub Actions runner autoscaler

BetaOpen SourceApache-2.0
Updated4 months ago
LanguageGo
Setup difficultyAdvanced
Stars
428
Ports
9997 (API server and Web UI), 80 (API server and Web UI (example in quickstart guides))
Docker
ghcr.io/cloudbase/garm
Install with Docker
garm screenshot 1garm screenshot 2garm screenshot 3garm screenshot 4garm screenshot 5

What is garm?

GARM manages self-hosted GitHub Actions and Gitea runners by automatically provisioning ephemeral instances across AWS, Azure, GCP, OpenStack, Oracle Cloud, Kubernetes, LXD, Incus, and other infrastructure. It offers two scaling modes: webhook-driven pools with configurable balancing and native GitHub scale sets using GitHub's message queue. The software runs as a single binary with embedded SQLite (PostgreSQL optional), includes a built-in web UI, and uses a pluggable provider architecture where providers are standalone executables. Installation options include Docker, Docker Compose, systemd, and a Kubernetes operator maintained by Mercedes-Benz.

Should you self-host garm?

garm scores 51/100 on selfhost.directory (how scoring works) and ranks #20 of 28 in CI/CD. It has 428 GitHub stars.

It shipped 4 stable releases in the past year. The latest, v0.2.1, came out on 8 May 2026. New versions land roughly every 5 weeks.

Setup is advanced: plan for several services and some ongoing maintenance. An official Docker image is available. It is Apache-2.0-licensed and written mostly in Go.

Its closest alternative on selfhost.directory is jenkins (82/100, 26 704 stars). It scores higher overall, so compare the two before you pick. See garm vs jenkins side by side.

Features

  • Built-in web UI
  • GitHub Actions Runner Scale Sets
  • Live log streaming
  • Multi-cloud runner management
  • Pluggable provider architecture
  • Prometheus Metrics
  • Scale to Zero
  • Single binary with embedded SQLite
  • Webhook-driven runner pools

garm README

How to install garm

Install garm with Docker

docker run -d
--name garm
-p 80:80
-v /etc/garm:/etc/garm:rw
-v /var/snap/lxd/common/lxd/unix.socket:/var/snap/lxd/common/lxd/unix.socket:rw
ghcr.io/cloudbase/garm:v0.2.0-beta1

Requires LXD installed and initialized on host; config at /etc/garm/config.toml

garm releases & version history

FAQ

What should I set the bootstrap timeout to?

Default is 20 minutes. Increase if your provider or image takes longer to boot (e.g., bare metal, large Windows images); decrease for faster detection of failed runners.

How do I update a pool's image without downtime?

Run garm-cli pool update <POOL_ID> --image=new-image:latest. Existing runners continue using the old image until replaced; new runners use the updated image.

Can I share pools across multiple repos?

Not directly at the pool level, but you can create an organization-level pool which serves all repositories in that org, effectively sharing runners across repos.

How does pool balancing work?

When a job's labels match multiple pools, the pool balancer decides: round-robin (default) distributes evenly across matching pools; pack fills the highest-priority pool first, then overflows to others.

What happens when my credentials hit the forge API rate limit?

GARM tracks rate limits from forge API responses. When quota is exhausted, workers needing forge API calls pause and resume automatically once the quota resets. A slice can be reserved for critical cleanup operations.

I lost my admin password. How do I reset it?

Use the garm daemon binary (not garm-cli) with the admin subcommand: garm --config /etc/garm/config.toml admin password-reset --new-password '<new password>' admin

Is the GARM API secure?

GARM uses JWT authentication. The API should be placed behind a reverse proxy with TLS termination for production use. All sensitive data is encrypted at rest.

Does GARM need a public webhook endpoint?

Only for pools (not scale sets). The webhook URL must be reachable by GitHub.com or your GHES/Gitea server. Scale sets use GitHub's message queue instead.

How do I upgrade GARM?

Stop the service, replace the binary, and start it again — database migrations run automatically at startup. Note version-specific migration requirements for v0.2.1 and v0.2.2+.

What database does GARM use?

SQLite3 by default (single file, no external server required); PostgreSQL is also supported for deployments preferring an external database.

Can GARM scale to zero?

Yes, by setting min-idle-runners=0 on a pool, GARM will only create runners in response to queued jobs, though this adds startup latency of typically 1-3 minutes.

What infrastructure providers are available?

Amazon EC2, Azure, CloudStack, GCP, Incus, Kubernetes, LXD, OpenStack, and Oracle OCI. Custom providers can also be built.

Which forges does GARM support?

GARM supports GitHub.com, GitHub Enterprise Server (GHES), and Gitea (1.24+).

What is GARM?

GARM (GitHub Actions Runner Manager) is an open-source tool that manages GitHub Actions self-hosted runners, automatically creating and destroying runner instances in response to workflow jobs across multiple infrastructure providers.

Rate this project

Click to rate — no account needed.

0 comments

Posting as guest
Loading comments…