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%