Skip to content

fix(runner): serve action archives from a local cache and make the compose setup generic - #25

Merged
azlekov merged 1 commit into
mainfrom
fix/runner-action-archive-cache
Oct 15, 2026
Merged

azlekov merged 1 commit into
mainfrom
fix/runner-action-archive-cache

Conversation

@azlekov

@azlekov azlekov commented Oct 15, 2026 •

Copy link
Copy Markdown

Problem

Ephemeral runners download every uses: action archive on every job. Several runners behind one IP hit codeload's rate limit and fail in "Set up job":

Failed to download archive 'https://codeload.github.com/actions/checkout/tar.gz/<sha>' after 3 attempts ... 429 (Too Many Requests)

Change

  • Action archive cache. The runner (2.338.0) reads ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE/<owner>_<repo>/<sha>.tar.gz before downloading, but never writes it (Runner.Worker/ActionManager.cs). A shared runner-action-cache volume is mounted read-only into every runner. The pruner fills it hourly, authenticated as the GitHub App, from the uses: refs in PREFETCH_SOURCES plus PREFETCH_EXTRA, and caps it at 2 GiB. It is opt-in: with neither set, nothing happens. pruner.sh prefetch warms it once.
  • Generic setup. Neutral defaults (LABELS=docker, overridable RUNNER_IMAGE, empty PREFETCH_SOURCES), one generic .env.example, and hosts/no-caches.compose.yml for small hosts (replaces the per-host examples and hosts/rpi5.compose.yml).
  • README. Rewritten for any user: quick start, how to fit it to one or many hosts and capability labels, caches, the action cache, maintenance, tags. 343 → 175 lines.

Rollout on existing hosts

  1. git pull && docker compose pull && docker compose up -d
  2. To use the cache, set PREFETCH_SOURCES (e.g. the repo holding your reusable workflows) and/or PREFETCH_EXTRA in .env, then docker compose run --rm pruner prefetch.
  3. Hosts that layered hosts/rpi5.compose.yml must switch COMPOSE_FILE to docker-compose.yml:hosts/no-caches.compose.yml.

Verification

  • docker compose config passes for the base file and with the no-caches override.
  • shellcheck and bash -n are clean.
  • A live prefetch_one call cached actions/checkout@v4 as actions_checkout/<sha>.tar.gz, and a repeat call skipped the download.
  • Not yet observed: a cache hit in a real job ("Set up job" with debug logging shows Copied action archive ...).

🤖 Generated with Claude Code

…mpose setup generic

Ephemeral runners download every action archive on every job, and several runners behind one IP hit
codeload's 429 limit in "Set up job". The runner reads ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE before
downloading but never writes it, so:

- mount a shared runner-action-cache volume read-only into every runner and set the env var;
- let the pruner fill it hourly, authenticated as the GitHub App, from the `uses:` refs in
  PREFETCH_SOURCES plus PREFETCH_EXTRA (opt-in, skipped when neither is set), with an LRU cap;
- `pruner.sh prefetch` warms it once after a rollout.

Make the setup usable by any organization: neutral defaults (LABELS=docker, RUNNER_IMAGE overridable,
empty PREFETCH_SOURCES), one generic .env.example, hosts/no-caches.compose.yml for small hosts, and a
shorter README that explains how to fit the setup to different hosts and labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@azlekov
azlekov force-pushed the fix/runner-action-archive-cache branch from 0456592 to 92c7808 Compare October 15, 2026 14:27
@azlekov azlekov changed the title fix(runner): serve action archives from a shared local cache to stop codeload 429s fix(runner): serve action archives from a local cache and make the compose setup generic Oct 15, 2026
@azlekov
azlekov merged commit d0fd256 into main Oct 15, 2026
12 checks passed
@azlekov
azlekov deleted the fix/runner-action-archive-cache branch October 15, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant