feat: runner install — GitHub Actions runner as an unprivileged systemd service #3
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:bootstrap
scope:coolify
scope:db
scope:docs
scope:drill
scope:installer
scope:labels
scope:platform
scope:runner
scope:users
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/rig#3
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/runner-install"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Two additions, plan-first (
docs/plans/2026-07-11-runner-install.mdis the first commit; an addendum covers the second feature):rig runner install --repo <owner/repo> --version <pin> [--name|--labels|--user]— turns a bootstrapped box into a self-hosted GitHub Actions runner: the officialactions/runneragent installed at an explicit version pin as a systemd service under an unprivileged user (defaultgithub-runner, created if absent, never root, no supplementary groups).rig bootstrap runner— a third bootstrap role alongsidecontrol-plane|workload. It defaults--ts-tagtotag:ciand refusestag:server(exit 2): a runner executes repo-controlled code, and advertising the server tag would extend every grant your servers hold to that code. The pairing rhymes with the existing shape:bootstrap control-plane→coolify install,bootstrap runner→runner install.Why this shape
dockergroup membership is root-equivalent (the socket is a root API). On a box whose design goal is a narrow blast radius for repo-controlled code, that is a gratuitous path to root. Docker arrives only when a job genuinely needs it, with the isolation model revisited then.RUNNER_TOKENenv var or a silent interactive prompt, is consumed byconfig.shin memory, and is never written to disk or logged by rig.coolify installyou state what you install; unlike Coolify the runner then self-updates — GitHub refuses stale runners, so freezing it means it silently stops taking jobs.Testing
bash test/cli.sh: 27 passed, 0 failed (11 new cases: usage/validation/refusal paths, including the non-root refusals,--user rootrejection, and therunner-roletag:serverrefusal).shellcheck install.sh bin/rig commands/*.sh test/cli.sh: clean at default severity.bootstrap runner→runner installwith a real registration token → runner shows Idle → convergent second run).🤖 Generated with Claude Code