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=dicerdicer 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: 4GiBdicer 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 -hand 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_runnerson 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.