fix(ci): disable broken pnpm cache on actions/setup-node
CI / scan (pull_request) Failing after 1m27s
CI / commits (pull_request) Successful in 1m28s
CI / check (pull_request) Successful in 1m34s
CI / a11y (pull_request) Successful in 1m3s
CI / perf (pull_request) Successful in 1m52s

`act_runner`'s built-in GitHub-Actions-cache server binds inside the
runner container on the compose-defined `apf-portal-act-runners`
bridge. Jobs spawned via the mounted Docker socket come up on
Docker's default `bridge` network and cannot reach it. Every job
opting into `cache: 'pnpm'` therefore eats ~2 min ETIMEDOUT on
restore at the start and another ~2 min on save at the end — for
zero cache hits. Across the five jobs that's ~20 min wasted per CI
run.

Drop `cache: 'pnpm'` from all five jobs. `pnpm install
--frozen-lockfile` is fast enough on the warm store inside the job
container that the cache layer is currently no value-add anyway.

Document the proper fix (cross-container networking / fixed-port
cache binding) in infra/README.md so a future infra spike can
re-enable caching cleanly.
This commit is contained in:
Julien Gautier
2026-05-04 14:53:15 +02:00
parent b7adf2e308
commit 9a57f21c6d
2 changed files with 22 additions and 5 deletions
+13
View File
@@ -62,6 +62,19 @@ The compose mounts `/var/run/docker.sock` into each runner so jobs can spawn con
- **No host filesystem mounts beyond the docker socket:** the compose intentionally does not mount `/`, `/etc`, or any project source. Workflows that need data on the host must do so via Docker volumes.
- **Future hardening (out of scope of v1):** migrate to **rootless Docker** on the runner host, or to a **DinD (Docker-in-Docker) sidecar** so the runner cannot escape into the host daemon. Decided when the org's RSSI confirms the security posture, or when the runner host is shared with anything else of value.
### Cache server (deferred)
`act_runner` ships a built-in GitHub-Actions-cache-compatible server, used by `actions/setup-node@v4` (`cache: 'pnpm'`), `actions/cache`, and similar. In the current setup it does **not** work because the runner containers and the job containers live on different Docker networks: the runner is on the compose-defined `apf-portal-act-runners` bridge, while jobs spawned via the mounted `/var/run/docker.sock` come up on Docker's default `bridge` network. The cache server binds inside the runner container on a random port — unreachable from the job. The symptom is a ~2 min `ETIMEDOUT` at the start (restore) and end (save) of every job that opts into caching.
For now `cache: 'pnpm'` is left **disabled** in `.gitea/workflows/ci.yml`. `pnpm install --frozen-lockfile` is fast enough on a warm pnpm store inside the job image (~3060 s cold) that the cache layer adds no value as long as it doesn't actually transfer anything.
When this is reactivated, the right fix is one of:
- attach jobs to the same Docker network as the runners (`runner.container.network` in act_runner's `config.yaml`, then advertise the cache `host` on the bridge IP); or
- bind act_runner's cache server on a fixed `host_port` reachable from any container (host gateway IP), and set `ACTIONS_CACHE_URL` accordingly.
Either path needs a single-runner spike before being rolled out to the three.
### Image pinning
The compose pins `gitea/act_runner:0.2.13`. Update the pin deliberately, not via `:latest`: