Files
esh-pfi-infrastructure/stacks/gitea-runner/conf/config.yaml
T
vh 89ffab69df docs(gitea-runner): record measured job capabilities, incl. root-equivalent docker access
Answering a CI-posture question from vastblue-dev meant measuring three
things rather than recalling them. Two came back the opposite of the way
the config reads:

- `container.valid_volumes: []` does NOT keep the docker daemon out of
  jobs. act_runner mounts /var/run/docker.sock on its own, so every job
  on the shared runner is uid 0 with `docker ps` over all 49 containers
  on ana-docker — gitea, synapse, phasefinal-web, adguardhome included.
  It is also load-bearing: four repos drive buildx through it, so the
  fix is isolation onto a dedicated runner, not tightening this one.
- A full-URL `uses: https://gitea.phasefinal.com/actions/checkout@v4`
  resolves from the local mirrors today. That is github-independence per
  workflow without the DEFAULT_ACTIONS_URL flip that has been parked on
  act_runner's action-fetch auth since 2026-08-05.

Also recorded: `services:` containers work (Postgres 16 on the service
name), job images need a node binary for JS actions, and `/actions/runs`
lists runs that `/actions/tasks` reports as empty on gitea 1.26.1.

Measured on a throwaway repo under the claude-bot account, since deleted.
config.yaml change is comment-only and deliberately not deployed — it
would bounce the runner for no runtime effect.
2026-09-02 08:57:25 -07:00

68 lines
2.2 KiB
YAML

# act_runner config. Mounted into the runner container at
# /data/config.yaml (CONFIG_FILE env var points here).
#
# Reference: https://docs.gitea.com/usage/actions/act-runner
log:
level: info
runner:
# Persisted registration credentials. Created on first successful
# `register`; reused on subsequent starts.
file: /data/.runner
# Max parallel jobs this runner will accept.
capacity: 2
# Hard timeout per job — covers a wedged docker build, a hung ssh,
# etc. 30m is generous for our deploy workflows (mostly seconds).
timeout: 30m
# Time given to a job to clean up after a SIGTERM before SIGKILL.
shutdown_timeout: 1m
# TLS verification when talking to gitea. KEEP true in prod.
insecure: false
# Polling cadence + per-poll HTTP timeout.
fetch_timeout: 5s
fetch_interval: 2s
cache:
# Provides actions-cache-compatible storage for `actions/cache`.
enabled: true
dir: /data/cache
container:
# Job containers join this docker network. Lets workflow steps
# talk to other compose services (gitea itself, registries, etc.)
# by container name.
network: traefik-net
privileged: false
# Job containers' working dir is mounted under here on the host
# (via the runner's docker.sock spawning). Kept on the runner's
# /data volume so workspaces persist briefly between steps.
workdir_parent: /data/workspace
# Volumes a WORKFLOW may bind-mount into its job container. Keep tight.
#
# ⚠ This does NOT keep the docker daemon out of jobs, and reading it that
# way is the mistake. act_runner mounts /var/run/docker.sock into every job
# container on its own, independently of this list. Measured 2026-09-02: a
# job running `docker:27-cli` is uid 0, sees all 49 containers on this host
# via `docker ps`, and has `docker compose v2.33.0` on PATH.
#
# So every job on this runner has root-equivalent control of ana-docker —
# which hosts gitea itself, synapse, phasefinal-web and adguardhome. It is
# also LOAD-BEARING: vh/Worldtree, vh/soong-lab, vh/skaldsong and
# vh/wt-matrix-bridge all drive buildx through that socket, so it cannot
# simply be closed. Isolate sensitive work onto its own runner instead.
valid_volumes: []
force_pull: false
host:
workdir_parent: /data/host-workspace