Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,20 @@ runner-kubeconfig: ## Refresh the runner's kubeconfig (rewrites 127.0.0.1 → k8
kubectl config view --context $(CONTEXT) --minify --raw | sed 's|127.0.0.1|k8s.orb.local|g' > $(HOME)/.config/runner-kubeconfig
chmod 600 $(HOME)/.config/runner-kubeconfig

runner-foreground: runner-kubeconfig ## Run runner in foreground (used by LaunchAgent)
# runner-preflight catches the most common silent failure mode: Doppler
# returns a missing/empty GH_PAT_RUNNER_TOKEN, the compose interpolation
# error gets buried in stderr, and the LaunchAgent throttles every 30s with
# nothing visible upstream. This single test fails loud at the top of the
# stack so the user sees the actionable error in `~/Library/Logs/orbstack-runner/stderr.log`.
runner-preflight:
@doppler run -p $(DOPPLER_RUNNER_PROJ) -c $(DOPPLER_RUNNER_CONFIG) -- \
sh -c 'test -n "$$GH_PAT_RUNNER_TOKEN" || { echo "ERROR: GH_PAT_RUNNER_TOKEN missing from doppler $(DOPPLER_RUNNER_PROJ)/$(DOPPLER_RUNNER_CONFIG). Refresh the fine-grained PAT before retrying." >&2; exit 1; }'

runner-foreground: runner-kubeconfig runner-preflight ## Run runner in foreground (used by LaunchAgent)
doppler run -p $(DOPPLER_RUNNER_PROJ) -c $(DOPPLER_RUNNER_CONFIG) -- \
docker compose -f $(RUNNER_COMPOSE) -p $(RUNNER_PROJECT) up

runner-start: runner-kubeconfig ## Start runner in background (manual one-shot)
runner-start: runner-kubeconfig runner-preflight ## Start runner in background (manual one-shot)
doppler run -p $(DOPPLER_RUNNER_PROJ) -c $(DOPPLER_RUNNER_CONFIG) -- \
docker compose -f $(RUNNER_COMPOSE) -p $(RUNNER_PROJECT) up -d

Expand Down Expand Up @@ -209,8 +218,9 @@ runner-doctor: runner-doctor-container runner-doctor-github runner-doctor-mounts

runner-doctor-container:
@echo "─── Container state ───"
docker inspect $(RUNNER_CONTAINER) --format 'state: {{.State.Status}} restartCount: {{.RestartCount}} exitCode: {{.State.ExitCode}}'
docker inspect $(RUNNER_CONTAINER) --format 'state: {{.State.Status}} health: {{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}} restartCount: {{.RestartCount}} exitCode: {{.State.ExitCode}}'
docker inspect $(RUNNER_CONTAINER) --format '{{eq .State.Status "running"}}' | grep -q '^true$$'
docker inspect $(RUNNER_CONTAINER) --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' | grep -qE '^(healthy|starting|none)$$'

runner-doctor-github:
@echo "─── GitHub registration ───"
Expand Down
21 changes: 19 additions & 2 deletions docker/actions-runner/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,32 @@ services:
container_name: orbstack-runner
# Pinned to ubuntu-jammy (22.04) — `latest` resolves to ubuntu-focal (20.04)
# which lacks arm64 builds for Python 3.14 used by setup-e2e-tools.
image: myoung34/github-runner:ubuntu-jammy
# Digest pin (Renovate-managed): forces deterministic pulls and keeps a
# supply-chain audit trail. Renovate's docker-compose manager updates the
# digest when myoung34 publishes a new ubuntu-jammy build.
image: myoung34/github-runner:ubuntu-jammy@sha256:0d483ed415f456654622c73516ed0cd499a39e9c7fe5f6718b2a2c8b0f76e218
restart: unless-stopped
# Healthcheck: the runner doesn't expose a port but it absolutely needs
# to be able to reach api.github.com to register and pull jobs. A failing
# check surfaces in `docker compose ps` and is wired into `make
# runner-doctor` so silent network/DNS regressions are visible quickly.
healthcheck:
test: ["CMD-SHELL", "curl -fsS -m 5 https://api.github.com/zen >/dev/null"]
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
environment:
RUNNER_SCOPE: repo
REPO_URL: https://github.com/${GITHUB_REPO:-JacobPEvans/orbstack-kubernetes}
RUNNER_NAME: orbstack-runner
LABELS: self-hosted,Linux,ARM64
EPHEMERAL: "1"
DISABLE_AUTO_UPDATE: "1"
# DISABLE_AUTO_UPDATE removed: the actions/runner binary baked into the
# myoung34 image self-updates on registration when GitHub publishes a
# newer runner. Combined with the Renovate-managed image digest pin
# above, this keeps both the OS layer and the runner agent current
# without manual `docker pull` cycles.
ACCESS_TOKEN: ${GH_PAT_RUNNER_TOKEN:?GH_PAT_RUNNER_TOKEN must be set (use doppler run -p gh-workflow-tokens -c prd)}
# ─── Path-mirroring strategy ───────────────────────────────────────────
# The container bind-mounts the macOS user home in-place so paths are
Expand Down
Loading