Problem
Both Dockerfile and Dockerfile.analysis re-run the same expensive steps on every CI build:
go mod download for the full dependency tree
- (analysis only)
apt-get install chromium chromium-sandbox ca-certificates fonts-liberation dumb-init
Combined, these account for roughly 60–90s of every shared-image and analysis-image build. With pool reconcile now decoupled (PR #378), Docker build is one of the bigger remaining items on the review-app critical path.
Proposal
Bake go mod download and Chromium into a hover-base image, rebuild it nightly (or on dependency change), and have Dockerfile / Dockerfile.analysis FROM it.
Scope
- New
Dockerfile.base — golang:1.26.3-alpine plus:
COPY go.mod go.sum ./ + go mod download
- For an
analysis-base variant: apt-get install Chromium + fonts + dumb-init
- New workflow
.github/workflows/build-base-image.yml:
- Schedule: nightly +
workflow_dispatch
- Path triggers:
go.mod, go.sum, Dockerfile.base, the Chromium package list
- Pushes to
registry.fly.io/hover-base:<sha> and :latest (or ghcr.io)
- Update
Dockerfile / Dockerfile.analysis:
FROM hover-base:latest AS builder
- Drop the now-redundant
go mod download / apt-get lines
- Bootstrap: first PR after a base bump needs the new base built before it builds — handle via
workflow_call from PR build, or accept one slow build.
Expected saving
~60s off the critical path of every review-app and prod deploy.
Risks / open questions
- Cache invalidation when go.mod changes — should the base build be a hard prereq for the PR build, or "best effort, fall back to inline install"?
- Storage cost of nightly tagged base images — set retention on the registry.
- Slight coupling: a broken nightly base build would block all subsequent PR builds. Mitigate with a green-tag-only pull (
:latest only updated on successful build).
Effort
Estimated half a day. Separate from #377 / PR #378.
Problem
Both
DockerfileandDockerfile.analysisre-run the same expensive steps on every CI build:go mod downloadfor the full dependency treeapt-get install chromium chromium-sandbox ca-certificates fonts-liberation dumb-initCombined, these account for roughly 60–90s of every shared-image and analysis-image build. With pool reconcile now decoupled (PR #378), Docker build is one of the bigger remaining items on the review-app critical path.
Proposal
Bake
go mod downloadand Chromium into ahover-baseimage, rebuild it nightly (or on dependency change), and haveDockerfile/Dockerfile.analysisFROMit.Scope
Dockerfile.base—golang:1.26.3-alpineplus:COPY go.mod go.sum ./+go mod downloadanalysis-basevariant:apt-get installChromium + fonts + dumb-init.github/workflows/build-base-image.yml:workflow_dispatchgo.mod,go.sum,Dockerfile.base, the Chromium package listregistry.fly.io/hover-base:<sha>and:latest(or ghcr.io)Dockerfile/Dockerfile.analysis:FROM hover-base:latest AS buildergo mod download/apt-getlinesworkflow_callfrom PR build, or accept one slow build.Expected saving
~60s off the critical path of every review-app and prod deploy.
Risks / open questions
:latestonly updated on successful build).Effort
Estimated half a day. Separate from #377 / PR #378.