infra/forgejo: raise LAN runner concurrency, document why prod/beta aren't candidates
All checks were successful
PR build (required check) / changes (pull_request) Successful in 6s
secrets-guard / encrypted (pull_request) Successful in 5s
PR build (required check) / build-backend (pull_request) Has been skipped
shell-lint / shellcheck (pull_request) Successful in 8s
PR build (required check) / build-frontend (pull_request) Has been skipped
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / gate (pull_request) Successful in 3s

A single PR push fires pr-build, secrets-guard, and shell-lint as three
independent workflows with no dependency between them, so the previous
capacity (3, an earlier undocumented hand-tune of the tool's default of
1) already serializes build-backend/build-frontend/validate-observability
behind them even with 16 idle cores on the runner host. Raise to 8 and
track it in register-lan-runner.sh so a re-provision doesn't silently
drop back to the default.

Also document why more capacity belongs on the desktop rather than a
runner on prod/beta: docker_host: automount gives job containers the
host's own Docker socket, which on a live app or Forgejo host means any
CI job gets root-equivalent access to what else is running there. An
earlier stack revision did run the runner on beta and was reverted for
this reason.
This commit is contained in:
Emi Griffith 2026-07-24 12:04:35 -07:00
parent 88f5d0cce0
commit 1660de6cc6
2 changed files with 27 additions and 4 deletions

View file

@ -107,6 +107,25 @@ See that script's header for exactly what it replaces (the pre-Forgejo GitHub
self-hosted runner on this same machine) and why it registers with two self-hosted runner on this same machine) and why it registers with two
labels where there used to be two separate runners. labels where there used to be two separate runners.
`config.yaml`'s `runner.capacity` is raised from the tool's default of 1 to 8
(override with `CAPACITY=`) — a single PR push fires `pr-build`,
`secrets-guard`, and `shell-lint` simultaneously (3 independent workflows,
no `needs:` between them), so capacity 1 serializes work that could run in
parallel, and even capacity 3 (an earlier, undocumented hand-tune) leaves
`build-backend`/`build-frontend`/`validate-observability` queued behind
those three before they get a slot. The desktop has 16 cores / 34GB free
today; 8 concurrent jobs is comfortable headroom without starving LAN dev's
own compose stack.
**Adding more runner capacity should mean raising this number, or adding a
second runner on the desktop itself — not putting a runner on prod or
beta.** `container.docker_host: automount` gives job containers the *host's*
Docker socket; on prod or beta that would mean any CI job has root-equivalent
access to whatever else is running there (the live app stack, or Forgejo
itself). An earlier revision of this stack actually did run the runner as a
Swarm-hosted container on beta and was deliberately reverted to the desktop
for this reason — see the note at the top of `docker-stack.yml`.
## Custom CI job image (`ci-runner/`) ## Custom CI job image (`ci-runner/`)
`ci-runner/Dockerfile` still bases on `node:20-bookworm` — Node is a hard `ci-runner/Dockerfile` still bases on `node:20-bookworm` — Node is a hard

View file

@ -62,11 +62,15 @@ echo "==> Registering with $FORGEJO_URL (label: $LABELS)"
--name "thermograph-lan-$(hostname -s)" \ --name "thermograph-lan-$(hostname -s)" \
--labels "$LABELS" --labels "$LABELS"
echo "==> Runner config (docker.sock automount, so docker:-labeled jobs like" echo "==> Runner config (docker.sock automount so docker:-labeled jobs like"
echo " build-push.yml can actually run 'docker build/push' -- generated" echo " build-push.yml can actually run 'docker build/push'; capacity raised"
echo " config only overridden on the one setting that matters here)" echo " from the default of 1 -- a single PR push fires 3+ independent"
echo " workflows (pr-build, secrets-guard, shell-lint) simultaneously, so"
echo " anything less than that serializes jobs that could run in parallel)"
CAPACITY="${CAPACITY:-8}"
./forgejo-runner generate-config \ ./forgejo-runner generate-config \
| sed 's/docker_host: "-"/docker_host: "automount"/' \ | sed -e 's/docker_host: "-"/docker_host: "automount"/' \
-e "s/capacity: 1/capacity: ${CAPACITY}/" \
> "${RUNNER_DIR}/config.yaml" > "${RUNNER_DIR}/config.yaml"
echo "==> systemd --user unit" echo "==> systemd --user unit"