Self-Hosted Runner - How to develop and validate the `svc-runner` role on your own machine

:person_running: Self-Hosted Runners — Part 1: Try the Runner on Your Own Machine

Tutorial · Getting Started · written for the hub Tutorials category

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


:waving_hand: Hey! Want to see the Infinito.Nexus CI runner actually work — build an image and deploy a real app — without touching GitHub, a server, or anyone else’s stack? That’s what this guide does. By the end you’ll have run the runner’s full self-test on your own laptop, in a sealed sandbox that cleans up after itself.

:brick: First time here? Set up your machine first — see Part 3: Set Up Your Computer (or the full Installation Guide). This tutorial is only about the runner.


:thinking: What does “test the runner locally” even mean?

The svc-runner role ships its own end-to-end test. When you deploy the role, test-e2e-cli notices it (it declares templates/test.env.j2) and runs files/test/test.sh, which does two things:

  • :green_circle: local.sh — runs entirely on your machine, no GitHub. ← this is the fun part

  • :blue_circle: external.sh — the GitHub job-pickup smoke test; skips automatically when there’s no token

So you can exercise basically everything locally.

:microscope: What local.sh does, step by step

1. 🩺 checks the runner containers are healthy + the Docker socket works

2. 📦 container cp → copies this repo into runner-1

3. 🔨 make build → builds the Infinito image LOCALLY (no GHCR pull)

4. 📦 spins up a sealed, throwaway docker:dind sandbox

5. 🚀 deploys web-app-dashboard (everything else off) INSIDE that sandbox

6. 🧹 tears the sandbox down on exit — your real stack is never touched

No PAT, no GHCR login, no registration. Just your machine.

:white_check_mark: What you need

  • A working dev stack: make install && make compose-up (see the install guide above)

  • Docker with a reachable socket

  • :hot_beverage: Patience + disk: this is a real nested deploy — budget tens of GB and a long run

:rocket: Run it

make compose-deploy apps=svc-runner

Watch it live in another terminal:

tail -f /tmp/ansible-runner-dind-test.log

:bullseye: You’re looking for, in order:

  • running full local deploy test inside … → the sandbox deploy started

  • the web-app-dashboard deploy finishing

  • :white_check_mark: ALL LOCAL CHECKS PASSED (DinD)

:high_voltage: “Why did it skip the big deploy the second time?”

Each app deploys twice (sync + async). The heavy nested deploy only runs on the sync pass; on the async pass you’ll see:

Skipping full deploy on async pass (validated on sync pass)

That’s on purpose — it roughly halves the runtime. :+1:

:bullseye: But how do I test other roles with it — like matomo?

Great question — because deploying apps is the runner’s actual job. The web-app-dashboard in local.sh is just the runner’s own smoke test (“can I build an image and deploy something?”). The real value is running a deploy-test for any app.

In CI

You don’t pick by hand — the matrix automatically routes a job per changed app to the runners. Touch web-app-matomo → a matomo deploy-test lands on a runner. Touch nextcloud → same. (See Part 2.)

Locally

Run the exact same sandboxed deploy-test for any role yourself:

make compose-deploy apps=web-app-matomo                                  # deploy + test matomo

make compose-deploy apps=web-app-nextcloud                               # …or any role

make compose-deploy apps=web-app-matomo mode=reinstall full_cycle=true   # full sync+async cycle

This is the same machinery each runner job uses — one app, in an isolated stack. So “using the runner to test matomo” locally = running matomo’s deploy-test this way.

:light_bulb: In short: local.sh proves the runner works; make compose-deploy apps= is how you actually exercise other roles with the same mechanism.

:video_game: Want to drive a runner (not your local stack) to deploy a role you pick — on demand? That’s the CI: Manual trigger with a whitelist — see Part 2 → Manually pick which roles a runner deploys.

:hammer_and_wrench: Working on the role?

make test                              # fast: lint + rule tests (catches most mistakes)

make compose-deploy apps=svc-runner    # slow: the real end-to-end (sealed-sandbox deploy)

Heads up: make test does not run the nested deploy — that’s the compose-deploy line (and CI).


:backhand_index_pointing_right: Next in the series

  • Part 2: Plug your runners into CI

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

  • :open_book: Deep reference: roles/svc-runner/README.md

:receipt: Cheat sheet

make compose-up                          # dev stack up

make compose-deploy apps=svc-runner      # runs local.sh (the sealed-sandbox test)

tail -f /tmp/ansible-runner-dind-test.log

# 🎉 success = “ALL LOCAL CHECKS PASSED (DinD)”