Notes from a 2 AM On-Call: Why Gitea's Docker Build Ate 40 Minutes (And the 3-Line BuildKit Fix)
Description and use
Reordering ARGs in Gitea's Dockerfile restored 96 % cache hit rate, cutting build time from 40 min to 8 min and saving 68 % of CI resources.
Problem
Gitea self-hosted CI Docker builds suddenly grew from 8 min to 40 min due to repeated re‑downloading of Go module dependencies, despite no code changes.
Outcome
Reordering ARGs in Dockerfile restored 96 % cache hit rate, cutting build time from 40 min to 8 min and reducing weekly CI cost by 68 %.
Workflow
- 1. Identify cache miss on
go mod downloadstep via GitHub Actions logs. - 2. Inspect Dockerfile for ARG ordering; find
ARG GITEA_VERSIONbeforeWORKDIRandCOPY. - 3. Move volatile ARGs after dependency layers in Dockerfile.
- 4. Pin action versions and BuildKit image, scope cache by branch, and set build‑args.
- 5. Re‑run build; observe cache hit and reduced time.
Evidence
Step 12/18 : RUN go mod download ---> Running in 3a8f9c2d1e4b go: downloading github.com/... [... 2,847 dependencies streaming ...] time: 38m 42s
Gitea's Dockerfile had a subtle ARG ordering bug that invalidated BuildKit's layer fingerprinting.
Result: Build time dropped back to 7m 54s. Cache hit rate jumped from 12% to 96%.
- Record date: 2026-10-20T05:41:03.784Z