kvbox.sh
Guides

GitHub runners

A self-hosted GitHub Actions runner in one line, from the gh-runner image, registered at its first boot.

The gh-runner image is the base image (Docker included) plus GitHub's Actions runner. Give it your repo's URL and a registration token and it registers itself as a runner at its first boot.

On GitHub, open the repo's Settings → Actions → Runners → New self-hosted runner and copy the token from the config.sh line (--token AB12…). Then:

kvbox new ci --base gh-runner --size m \
  -e GITHUB_URL=https://github.com/<owner>/<repo> \
  -e GITHUB_RUNNER_TOKEN=AB12…
✓ box ci is running at 172.30.0.9: 4 vCPU, 8 GB RAM, 16 GB disk
  reach it at:  https://github.com/<owner>/<repo>/settings/actions/runners

Within a minute the runner shows as Idle on that page, with the labels self-hosted, Linux, X64, kvbox. Use it in a workflow:

jobs:
  build:
    runs-on: [self-hosted, kvbox]

For an org-wide runner, give the org's URL (https://github.com/<org>) and a token from the org's Settings → Actions → Runners.

Variables

  • GITHUB_URL: the repo or org the runner belongs to.
  • GITHUB_RUNNER_TOKEN: the registration token. It works once and expires within an hour, so make the box soon after copying it; the runner never needs it again.
  • GITHUB_RUNNER_NAME: the runner's name on GitHub (default: the box name).
  • GITHUB_RUNNER_LABELS: labels added to self-hosted, Linux, X64 (default kvbox; comma-separated).

The box registers once, at its first boot. After that the runner starts at every boot by itself: kvbox stop ci && kvbox start ci brings it back online. If the token had expired, kvbox exec ci -- journalctl -u kvbox-gh-runner-init says so; set a fresh one with kvbox env set GITHUB_RUNNER_TOKEN <token> --box ci and restart the box.

Sleeping between jobs

A runner keeps a connection open to GitHub, so it never hibernates on its own. Hibernate it yourself and let GitHub wake it with a wake hook:

kvbox vm hook create ci

Add the URL and the secret on GitHub as a webhook (repo Settings → Webhooks, content type application/json, event Workflow jobs). A queued job then wakes the box; the job starts once the runner is back online, a few seconds later. kvbox vm hibernate ci puts it to sleep again.

Removing a runner

kvbox rm ci removes the box, not the runner on GitHub: it stays listed as offline until you remove it on the repo's runners page. Don't fork or snapshot a registered runner into a second box: both would be the same runner on GitHub.

On this page