Self-Hosted Runners - Github Runners CI

:electric_plug: Self-Hosted Runners — Part 2: Plug Them into CI

Tutorial · Getting Started · written for the hub Tutorials category

Series: Part 1 — Local · Part 2 — CI · Part 3 — Your Computer


:waving_hand: So you’ve got runners ready (your machine set up + a box provisioned in Part 3). This guide shows how to make GitHub Actions actually send your CI deploy jobs to them — and how to turn that off in one command when you need to.

:brain: Want the big-picture overview of the whole test pipeline? See docs/administration/ci-runners.md.


:level_slider: The one knob you need to know

GitHub-hosted runners are the default — out of the box, everything runs on GitHub’s machines. Self-hosted runners are opt-in overflow, controlled by a single repository variable:

CI_SELF_HOSTED_RUNNER_COUNT What happens
0 / unset :blue_square: everything on GitHub-hosted (default, totally safe)
N :green_square: a proportional share of deploy jobs goes to your [self-hosted, linux] runners

That’s it. One variable flips the whole thing.

:green_circle: Turn it on

From your control machine:

make runner-ci-enable COUNT=2

# on a fork:
make runner-ci-enable COUNT=2 OWNER=youruser

This sets two repo variables for you:

  • CI_SELF_HOSTED_RUNNER_COUNT = COUNT → activates the split

  • INFINITO_TIMEOUT_MULTIPLIER = 30 → gives slower self-hosted hardware more breathing room (~1 h max wait)

:magnifying_glass_tilted_right: Check it landed:

github.com/<owner>/infinito-nexus/settings/variables/actions

Now push any commit — deploy jobs fan out across GitHub-hosted and your runners. :tada:

:red_circle: Turn it off (the panic button)

Machine down? Acting weird? One command sends everything back to GitHub:

make runner-ci-disable

# fork:
make runner-ci-disable OWNER=youruser

Nothing blocks — CI just reverts to GitHub-hosted instantly.

:railway_track: What happens when a job lands on your runner

GitHub dispatches a deploy job to [self-hosted, linux]
        │
        ▼
🏃 runner container (DooD — mounts the host docker socket)
        │  builds the Infinito image locally, then…
        ▼
📦 sealed throwaway docker daemon → deploys the app + runs Playwright/CLI tests
        │
        ▼
🧹 torn down on exit (host untouched)

Each runner instance is isolated (its own subnet, project name, volumes — keyed on the instance number), so several runners on one box happily run different apps in parallel without stepping on each other.

:video_game: Manually pick which roles a runner deploys

You don’t have to wait for a code change — there’s a manual trigger that lets you hand-pick the app(s) to deploy on a runner:

GitHub UI

Actions → :high_voltage: CI: ManualRun workflow

  • whitelist = the app ids you want, space-separated → e.g. web-app-matomo (or web-app-matomo web-app-nextcloud)

  • distros = e.g. debian

From your computer

gh workflow run entry-manual.yml --repo <owner>/infinito-nexus \
  -f distros="debian" \
  -f whitelist="web-app-matomo"

whitelist values:

  • explicit app ids → just those

  • __ALL__ → everything

  • empty → diff vs main

:backhand_index_pointing_right: With runners enabled (make runner-ci-enable), those jobs land on your runners, each deploying your chosen role in its isolated sandbox. This is how you drive a runner on demand — not just let CI feed it automatically.

:puzzle_piece: Good to know: when does the runner’s own test run?

  • The matrix only includes apps that changed (diff vs main). So svc-runner’s heavy local test fires only on PRs that touch svc-runner — not every run. :+1:

  • If svc-runner is changed and you have no self-hosted runners (COUNT=0), it doesn’t get skipped — it falls back to GitHub-hosted and runs there (local.sh runs; the GitHub-registration smoke test external.sh skips, since there’s no token). Exactly what you want for validating the role.


:backhand_index_pointing_right: Next / previous

  • Part 3: Set up your computer to work with it all

  • Part 1: Try the runner locally

:receipt: Cheat sheet

make runner-ci-enable  COUNT=2 [OWNER=youruser]   # 🟢 on

make runner-ci-disable         [OWNER=youruser]   # 🔴 off

# check:
github.com/<owner>/infinito-nexus/settings/variables/actions