Skip to content
This is the documentation for main, which is not released yet. Read the latest.

Quickstart

From one provider – a Dicer host, a Proxmox VE cluster, a Google Cloud project or an AWS account – to a workflow job running on a machine of its own.

You need:

  • a GitHub repository you administer. The runners serve only it: an organisation takes a different permission – Self-hosted runners in place of the repository’s Administration – as GitHub credentials sets out;
  • a Linux machine for Rungar, with systemd: for Dicer, the Dicer host itself;
  • a provider ready for runners, as its tab in Connect a provider sets out.

Create a GitHub App

Under your account or organisation, Settings → Developer settings → GitHub Apps → New GitHub App:

  • a name, and a homepage URL – the repository’s will do;
  • Webhook → Active unticked: Rungar asks GitHub for what it needs;
  • Repository permissions: Administration read and write. GitHub adds Metadata read by itself.

Create it, and note its Client ID. Under Private keys, generate one: GitHub hands over a .pem file, once. Then Install App, on the repository alone, and note the installation ID, the number that ends the installation’s URL: .../settings/installations/12345678.

Install Rungar

On Rungar’s machine:

$ curl -fsSL https://raw.githubusercontent.com/konradasb/rungar/main/scripts/install.sh | sudo bash

This installs rungar and its service, stopped, and the rungar user. See Installation for the packages, and what else it does.

Connect a provider

Let Rungar reach the provider, and write down the provider’s entry in the configuration, named main, for the next step. Each runner gets 2 vCPUs and 4 GiB.

Before you start: Dicer installed on the host, with a network and a kernel, as Dicer’s Quickstart sets up. Rungar reaches Dicer through its socket, so there is no network between the two to secure; the Dicer provider says how to reach hosts elsewhere.

Dicer’s socket is usable by the dicer group; the service runs as rungar. Give it the group with a drop-in, which an upgrade leaves alone:

$ sudo systemctl edit rungar

and add, between the comments:

[Service]
SupplementaryGroups=dicer
The dicer group is as much as root on the host, and so is rungar with it. Keep its members, and the configuration’s credentials, to whom you would give root.

The provider:

providers:
  - name: main
    type: dicer
    address: unix:///run/dicer/dicer.sock
    runner:
      image: ghcr.io/actions/actions-runner:latest
      vcpus: 2
      memory: 4GiB

dicer ps shows its runners.

Configure it

Put the App’s key where the service, and only the service, can read it:

$ sudo install -o root -g rungar -m 0640 my-app.private-key.pem /etc/rungar/app.pem

Then write /etc/rungar/config.yaml, with the repository’s URL, the App’s client and installation IDs, and the provider from the step above:

version: 1

github:
  url: https://github.com/my-org/my-repo
  app_client_id: Iv23liAbCdEf123456
  app_installation_id: 12345678
  app_private_key_path: /etc/rungar/app.pem

# The providers block from Connect a provider goes here.

# One scale set: the label workflows target, and at most two runners on the
# provider.
scale_sets:
  - name: rungar-c2-m4
    max_runners: 2
    providers: [main]
$ sudo chown root:rungar /etc/rungar/config.yaml
$ sudo chmod 0640 /etc/rungar/config.yaml

Start it

Check the configuration, start the daemon, and see what it is doing:

$ sudo -u rungar rungar validate
/etc/rungar/config.yaml is valid: 1 provider, 1 scale set
$ sudo systemctl enable --now rungar
$ sudo -u rungar rungar status

rungar status should show the credentials working, rungar-c2-m4 LISTENING, and main answering. On GitHub, the repository’s Settings → Actions → Runners now lists the scale set. It has no runners yet: Rungar creates one when a job asks for it. If something is not right, the daemon’s log says why:

$ journalctl -u rungar -n 50

Run a job

Add a workflow to the repository, .github/workflows/rungar.yaml:

name: rungar
on: workflow_dispatch

jobs:
  hello:
    runs-on: rungar-c2-m4
    steps:
      - run: |
          uname -a
          nproc
          free -h

and run it from the repository’s Actions tab. In the meantime, watch Rungar answer:

$ sudo -u rungar rungar events -f
2026-09-28 10:15:02   Runner   rungar-c2-m4-3f9a01c2   Created       Runner created on main: 2 vCPU, 4 GiB
2026-09-28 10:15:29   Runner   rungar-c2-m4-3f9a01c2   Connected     Runner connected to GitHub, 27s after its machine was created
2026-09-28 10:15:30   Runner   rungar-c2-m4-3f9a01c2   Job started   Job started: hello of my-org/my-repo, after waiting 31s, 30s of it for a runner
2026-09-28 10:15:41   Runner   rungar-c2-m4-3f9a01c2   Removed       Runner removed from main: its job completed

The job was queued; GitHub told Rungar; Rungar created a machine on the provider, registered only for that job; the job ran on it, printing two CPUs; and the machine was deleted. A second run gets a machine of its own. The provider shows it while it is there, as its tab says.

Where next

  • Keep a runner warm, so a job starts without waiting for a boot: min_runners on the scale set. See Scale sets.
  • More sizes, and more providers: see Designing runner sizes and Placement.
  • What to tighten before relying on runners – the image, the network, the identity jobs run as: see each provider’s notes, for Dicer, Proxmox VE, GCP and AWS.

Next steps