Keep the module cache out of the build stage's chown (closes #43)
check / check (push) Successful in 1m38s
check / check (push) Successful in 1m38s
The build stage handed /src and the whole Go module cache to the unprivileged user with chown -R, in a layer that re-ran on every source change. On this host that step took minutes and lately stalled script/cibuild outright. The module cache now sits at /go/pkg/mod and stays root's: bootstrap fills it as root and builder only reads it. The sources are copied with --chown. A small chown, cached with bootstrap, hands builder the /src directory itself, which git and make build need, and the telemetry files root's go commands left in its home. Tests and the build still run as builder. Model: opus-5-5
This commit is contained in:
+21
-8
@@ -51,14 +51,22 @@ RUN echo "gate lint, epoch ${CHECK_EPOCH}" && \
|
|||||||
FROM golang@sha256:56961d79ea8129efddcc0b8643fd8a5416b4e6228cfd477e3fd61deb2672c587 AS builder
|
FROM golang@sha256:56961d79ea8129efddcc0b8643fd8a5416b4e6228cfd477e3fd61deb2672c587 AS builder
|
||||||
|
|
||||||
# We never build or run as root. Create an unprivileged user and point
|
# We never build or run as root. Create an unprivileged user and point
|
||||||
# HOME and the Go caches at its home so go build and go test can write
|
# HOME and the build cache at its home so go build and go test can write
|
||||||
# their caches when we drop to it below. $GOPATH/bin is deliberately not
|
# it when we drop to it below. $GOPATH/bin is deliberately not on PATH:
|
||||||
# on PATH: script/bootstrap no longer `go install`s anything (the linter
|
# script/bootstrap no longer `go install`s anything (the linter runs
|
||||||
# runs from a pinned image, never from a host install), so nothing lands
|
# from a pinned image, never from a host install), so nothing lands
|
||||||
# there and adding it would only widen what this image resolves.
|
# there and adding it would only widen what this image resolves.
|
||||||
|
#
|
||||||
|
# The module cache is kept outside that home, at the base image's
|
||||||
|
# default /go/pkg/mod, and belongs to root: script/bootstrap fills it as
|
||||||
|
# root, and builder only reads it, which is all Go does with a cache
|
||||||
|
# that already holds every module. Do not move it into the home and
|
||||||
|
# hand it over with `chown -R`: that walks every file in it and can
|
||||||
|
# stall the build for half an hour on a loaded host.
|
||||||
RUN adduser -D -u 1000 builder
|
RUN adduser -D -u 1000 builder
|
||||||
ENV HOME=/home/builder
|
ENV HOME=/home/builder
|
||||||
ENV GOPATH=/home/builder/go
|
ENV GOPATH=/home/builder/go
|
||||||
|
ENV GOMODCACHE=/go/pkg/mod
|
||||||
ENV GOCACHE=/home/builder/.cache/go-build
|
ENV GOCACHE=/home/builder/.cache/go-build
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
@@ -83,11 +91,16 @@ COPY script/ script/
|
|||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
RUN script/bootstrap
|
RUN script/bootstrap
|
||||||
|
|
||||||
COPY . .
|
# /src itself must be builder's: make build writes the binary into it,
|
||||||
|
# and git refuses a repository whose top directory belongs to another
|
||||||
|
# user. The go commands bootstrap ran as root also left Go's telemetry
|
||||||
|
# files in builder's home. Both are a few small files, and this layer
|
||||||
|
# stays cached with bootstrap.
|
||||||
|
RUN chown builder:builder /src && chown -R builder:builder /home/builder
|
||||||
|
|
||||||
# Hand the sources and caches to the unprivileged user, then drop root
|
# The sources are handed to builder as they are copied, so no layer has
|
||||||
# before running any checks or builds.
|
# to walk them. Then drop root before running any checks or builds.
|
||||||
RUN chown -R builder:builder /src /home/builder
|
COPY --chown=builder:builder . .
|
||||||
USER builder
|
USER builder
|
||||||
|
|
||||||
# Fail the build unless the branch is green. Runs as non-root so the
|
# Fail the build unless the branch is green. Runs as non-root so the
|
||||||
|
|||||||
@@ -29,6 +29,10 @@
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- the `Dockerfile` build stage leaves the Go module cache root's and copies
|
||||||
|
the sources with `--chown`, so no `chown -R` walks them (2026-10-04,
|
||||||
|
https://git.eeqj.de/sneak/sfdupes/issues/43)
|
||||||
|
|
||||||
- warn about and skip symlink, socket, FIFO, device and `.zfs`
|
- warn about and skip symlink, socket, FIFO, device and `.zfs`
|
||||||
operands, keeping the records beneath them (2026-10-03,
|
operands, keeping the records beneath them (2026-10-03,
|
||||||
https://git.eeqj.de/sneak/sfdupes/issues/9)
|
https://git.eeqj.de/sneak/sfdupes/issues/9)
|
||||||
|
|||||||
Reference in New Issue
Block a user