The default was `tcp://buildkit.gitea.svc.cluster.local:1234`, which names aceofbase's namespace explicitly. That was correct while aceofbase was the only cluster running CI, and resolves to nothing from planet-express — so every workflow moved to the new dink-backed runner had to override it, and forgetting produced a DNS error from inside buildx that named neither this action nor the cluster it pointed at. A BARE Service name resolves in the job container's own namespace, which is where its runner's buildkit lives on both clusters: `gitea` on aceofbase, `gitea-runner` on planet-express. One default, correct on both, and correct for a cluster nobody has built yet. Verified before changing rather than assumed: on aceofbase the buildkit Service is in `gitea`, and gitea-act-runner's Role is namespace-scoped to `gitea`, so its job pods land in the same namespace as the Service. Existing consumers therefore see no change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C1tzpqzv37DDbtpPTxHsyA
setup-buildx
Drop-in replacement for docker/setup-buildx-action@v3 that defaults to the
buildkit service in the calling job's own namespace.
Use this whenever a Gitea Actions workflow needs to build images. It removes the boilerplate of declaring a remote driver every time, and ensures every build reuses the cluster's BuildKit instance (persistent 100 GiB Longhorn PVC + tuned GC) for layer caching across runs.
Usage
jobs:
build:
runs-on: aceofba-cluster
container:
image: ghcr.io/catthehacker/ubuntu:act-22.04
steps:
- uses: actions/checkout@v4
- uses: https://git.aceofba.se/infra/setup-buildx@v1
- uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
push: true
tags: git.aceofba.se/${{ github.repository }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
Inputs
| Name | Default | Description |
|---|---|---|
endpoint |
tcp://buildkit:1234 |
BuildKit TCP endpoint. A bare Service name, so it resolves in the job's own namespace. Override only if you run a private buildkit somewhere else. |
version |
latest |
buildx version, passed through to the upstream action. |
Why
docker/setup-buildx-action@v3 defaults to driver: docker-container, which
requires a working Docker daemon inside the job container. The act-runner
uses Kubernetes pod-per-job hooks — there is no dockerd in those pods. The
cluster does run a standalone BuildKit Service (buildkit-service Helm
chart, port 1234) which buildx can talk to via its remote driver. This
action wires that in by default.
cache-from/cache-to: type=gha also works out of the box: the act-runner
image (christopherhx/gitea-actions-runner) ships its own embedded Actions
Cache / Results API and injects ACTIONS_CACHE_URL / ACTIONS_RUNTIME_TOKEN
into the job container. That cache is persisted on the runner's /data PVC,
so it survives pod restarts. There is no separate cache-server deployment to
configure.
Why the endpoint is a bare Service name
A job container resolves a bare Service name in its own namespace, which is
where its runner's buildkit lives on every cluster here — gitea on
aceofbase, gitea-runner on planet-express. One default is therefore correct
on both, and stays correct for a cluster nobody has built yet.
Until 2026-08-18 it defaulted to tcp://buildkit.gitea.svc.cluster.local:1234,
naming aceofbase's namespace explicitly. That was fine while aceofbase was the
only cluster running CI. It resolved to nothing from planet-express, so every
workflow moved there had to pass endpoint: by hand, and forgetting produced a
DNS error from inside buildx that named neither this action nor the cluster it
was pointing at.