Registering a Runner

Registering a Self-Hosted Runner

A self-hosted runner is the open-source program behind GitHub 29 's own machines, actions/runner (https://github.com/actions/runner 6,293 ) (2.337.0 here), installed where you choose: a GPU server, a machine that can reach a staging database, an ARM board. It long-polls GitHub over outbound HTTPS, so it needs no open port, and registers with a one-hour token from the REST API. Settings > Actions > Runners prints a download, config.sh and run.sh sequence; BookNest runs the same program in a throwaway container:

Registering an ephemeral runner inside a container
RUNNER_TOKEN=$(gh api -X POST --jq .token \
  repos/{owner}/{repo}/actions/runners/registration-token)
docker run -d --name l1-runner --entrypoint sleep \
  ghcr.io/actions/actions-runner:2.337.0 infinity
docker exec l1-runner ./config.sh --unattended --ephemeral --disableupdate \
  --url https://github.com/binarybehemoth/booknest --token "$RUNNER_TOKEN" \
  --name l1-booknest-runner --labels l1-booknest-demo
unset RUNNER_TOKEN
Output
564cfe871302b024e03ca6e98c9db52ac0a8b60615cb4df751301568331d2d36
...
√ Runner successfully added
...

--ephemeral makes the runner take one job and then unregister; --disableupdate stops it replacing its own binary. Pull request #25 added self-hosted.yml, a workflow_dispatch workflow whose job prints where it ran. The owner dispatches it, and the container, with every file the runner wrote, is then deleted:

Running one job on the runner, then removing itShell
docker exec l1-runner ./run.sh > run.log 2>&1 &
gh workflow run self-hosted.yml && sleep 45
grep -v '^\[' run.log
docker rm -f l1-runner
gh api repos/{owner}/{repo}/actions/runners --jq .total_count
Output
https://github.com/binarybehemoth/booknest/actions/runs/36147682753
...
2026-09-25 14:28:15Z: Listening for Jobs
2026-09-25 14:28:19Z: Running job: where
2026-09-25 14:28:35Z: Job where completed with result: Succeeded
√ Removed .credentials
√ Removed .runner
...
l1-runner
0

The job's log printed user: runner on 564cfe871302: an unprivileged user inside the container. A persistent runner runs as a service (sudo ./svc.sh install) and is removed with ./config.sh remove --token <token>, using a token from the remove-token endpoint.