nampdnandClaude Fable 5.1 9f21d349f6 dind: split DNS -- ts.net via MagicDNS, everything else via Cloudflare
The host resolves the tailnet through MagicDNS on tailscale0 and everything
else through Cloudflare (systemd-resolved split DNS). MagicDNS has no
upstream for names outside the tailnet and answers them SERVFAIL, so
handing 100.100.100.100 to job containers as their first resolver made
every public lookup wait on a failure before falling back: image pulls
stalled and the e2e lane's *.localtest.me fetches blew a 5s poll.

A CoreDNS forwarder at a fixed address on the runner network now answers
both: ts.net is forwarded to MagicDNS, the rest to 1.1.1.1/1.0.0.1.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018j9YG8YFjcsVLnqzNz7LmA
2026-09-06 08:28:46 +07:00

Gitea Act Runner (DinD + cache)

Stable Gitea Actions runner for building Rust projects. Runs jobs in an isolated Docker-in-Docker daemon with the built-in cache server enabled and multiple parallel jobs.

Setup on a new build machine

Requires Docker + Docker Compose.

git clone https://git.vysma.dev/nampdn/act_runner.git && cd act_runner
cp .env.example .env
# edit .env: set GITEA_RUNNER_NAME (unique per machine) and a fresh
# GITEA_RUNNER_REGISTRATION_TOKEN from Gitea -> Actions -> Runners -> Create Runner
docker compose up -d

Nothing else to edit — config.yaml ships with working defaults. Tweak runner.capacity per machine if its CPU/RAM differ; that edit will show up as a local modification in git status, which is expected.

Verify:

docker compose ps                            # both containers up, dind healthy
docker logs gitea-runner-wsl 2>&1 | tail     # "declare successfully"

Config

  • Parallel jobs: config.yaml -> runner.capacity (default 4)

  • Job images: config.yaml -> runner.labels (ubuntu-latest/22.04/24.04)

  • Cache: config.yaml -> cache.dir: "/cache", mounted from the runner-cache volume. Docker layer cache persists separately in dind-storage.

    ⚠️ Leaving cache.dir empty makes act_runner write to $HOME/.cache/actcache — the container's writable layer, not a volume. Measured in production: 278 GB / 95 GB / 32 GB of cache sitting there across three machines, all of it destroyed by a single docker compose up -d. The two settings (cache.dir and the runner-cache mount) must always be changed together.

  • Runner image: pinned by digest, not :nightly. A floating tag means docker compose pull can recreate the container behind your back — and with it, wipe the cache. Upgrade deliberately: change the digest, commit, then apply.

Rust workflows

Copy example-rust-workflow.yaml to your repo at .gitea/workflows/build.yaml. It uses actions-rust-lang/setup-rust-toolchain which caches ~/.cargo and target/ via the runner's cache server.

Manage

docker compose up -d      # apply config changes
docker compose down       # stop (registration persists in volume)

⚠️ Check for running jobs before recreating the runner. Recreating it orphans any job in flight — Gitea marks them failed and you have to re-run:

docker exec gitea-runner-dind docker ps --format '{{.Names}}' | grep -v buildkit

Wait until that prints nothing (buildx_buildkit_builder-* is a helper, not a job).

Housekeeping

Job images, volumes and BuildKit cache pile up inside DinD and are never reaped automatically. Measured on one machine: 515 unused images and a 71 GB build cache.

docker exec gitea-runner-dind docker image prune -af --filter until=168h
docker exec gitea-runner-dind docker builder prune -f --keep-storage 20GB
# volume prune only removes *anonymous* volumes; task volumes are named:
for v in $(docker exec gitea-runner-dind docker volume ls -q | grep '^GITEA-ACTIONS-TASK'); do
  docker exec gitea-runner-dind docker volume rm "$v" 2>/dev/null
done

Keep act-toolcache and don't wipe the BuildKit cache outright — cap it instead.

Each machine needs a unique GITEA_RUNNER_NAME and its own registration token. Run docker compose down -v to fully reset (drops registration + caches).

S
Description
No description provided
Readme
54 KiB
Languages
Shell 100%