From e46515963a901bf9df63f11d379f0a4d6401ac31 Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Tue, 12 Nov 2024 16:33:42 -0500 Subject: [PATCH] Cache module dependencies between container builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tiger Kaovilai break up velero-builder stage to allow more concurrent layer builds. Signed-off-by: Tiger Kaovilai Add restic caching if fix_restic_cve.txt changes, only the dep added during patch will require redownload. ``` ❯ make container [+] Building 64.5s (20/20) FINISHED docker-container:colima-multiplat => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 3.24kB 0.0s => [internal] load metadata for docker.io/paketobuildpacks/run-jammy-tiny:latest 0.1s => [internal] load metadata for docker.io/library/golang:1.22-bookworm 0.1s => [internal] load .dockerignore 0.0s => => transferring context: 60B 0.0s => [stage-2 1/3] FROM docker.io/paketobuildpacks/run-jammy-tiny:latest@sha256:6a3b9424b0616c4c37309b3f3e410f305ad75c484ab74b0a624d22c8a33ae5ae 0.0s => => resolve docker.io/paketobuildpacks/run-jammy-tiny:latest@sha256:6a3b9424b0616c4c37309b3f3e410f305ad75c484ab74b0a624d22c8a33ae5ae 0.0s => [restic-builder 1/5] FROM docker.io/library/golang:1.22-bookworm@sha256:475ff60e52faaf037be2e7a1bc2ea5ea4aaa3396274af3def6545124a18b99b4 0.0s => => resolve docker.io/library/golang:1.22-bookworm@sha256:475ff60e52faaf037be2e7a1bc2ea5ea4aaa3396274af3def6545124a18b99b4 0.0s => [internal] load build context 0.3s => => transferring context: 546.21kB 0.3s => CACHED [restic-builder 2/5] RUN if [ "velero" = "velero" ]; then mkdir -p /build/restic && cd /build/restic && git clone --single-branch -b v0.15.0 https://github.com/restic/restic.git . && go mod download; fi 0.0s => [restic-builder 3/5] COPY hack/fix_restic_cve.txt /go/src/github.com/vmware-tanzu/velero/hack/ 0.0s => CACHED [velero-builder 2/6] WORKDIR /go/src/github.com/vmware-tanzu/velero 0.0s => CACHED [velero-builder 3/6] COPY go.mod go.sum /go/src/github.com/vmware-tanzu/velero/ 0.0s => CACHED [velero-builder 4/6] RUN go mod download 0.0s => [velero-builder 5/6] COPY . /go/src/github.com/vmware-tanzu/velero 6.5s => [restic-builder 4/5] RUN if [ "velero" = "velero" ]; then mkdir -p /output/usr/bin && cd /build/restic && git apply /go/src/github.com/vmware-tanzu/velero/hack/fix_restic_cve.txt && go mod download; fi 7.2s => [velero-builder 6/6] RUN mkdir -p /output/usr/bin && export GOARM=$( echo "" | cut -c2-) && go build -o /output/velero -ldflags "-X github.com/vmware-tanzu/velero/pkg/buildinfo.Version=main -X github.com/vmware-tanzu/velero/pkg/buildinfo.GitSHA=590f6df48d3fdc 55.5s => [restic-builder 5/5] RUN if [ "velero" = "velero" ]; then cd /build/restic && GOARM=$(echo "" | cut -c2-) go run build.go --goos "linux" --goarch "amd64" --goarm "" -o /output/usr/bin/restic && chmod +x /output/usr/bin/restic; fi && go cle 30.0s => CACHED [stage-2 2/3] COPY --from=velero-builder /output / 0.0s => CACHED [stage-2 3/3] COPY --from=restic-builder /output / 0.0s => exporting to docker image format 0.7s => => exporting layers 0.0s => => exporting manifest sha256:d275186bbf7b7fb08da8fe957037d8600c7b96693fe59bdfb119d977058daaa0 0.0s => => exporting config sha256:5cb88b0eac0b14df3efd549e0ca4df1980501a5f5cea677f0de1f5dd97050141 0.0s => => sending tarball 0.7s => importing to docker 0.0s container: velero/velero:main ``` Signed-off-by: Tiger Kaovilai --- Dockerfile | 55 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/Dockerfile b/Dockerfile index 25b314a1115..65e48695e8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ # limitations under the License. # Velero binary build section -FROM --platform=$BUILDPLATFORM golang:1.22-bookworm AS velero-builder +FROM --platform=$BUILDPLATFORM golang:1.22-bookworm AS velero-builder-base ARG GOPROXY ARG BIN @@ -34,17 +34,24 @@ ENV CGO_ENABLED=0 \ GOARM=${TARGETVARIANT} \ LDFLAGS="-X ${PKG}/pkg/buildinfo.Version=${VERSION} -X ${PKG}/pkg/buildinfo.GitSHA=${GIT_SHA} -X ${PKG}/pkg/buildinfo.GitTreeState=${GIT_TREE_STATE} -X ${PKG}/pkg/buildinfo.ImageRegistry=${REGISTRY}" +RUN mkdir -p /output/usr/bin WORKDIR /go/src/github.com/vmware-tanzu/velero - +COPY go.mod go.sum /go/src/github.com/vmware-tanzu/velero/ +# --mount=type=cache,target=/go/pkg/mod,id=vbb allows reuse of build cache across builds instead of invalidating whole cache when go.mod changes +# id is to allow other stages to use the same cache path without conflicting with this stage. +# velero-builder-helper and velero-builder share the same cache path and id to share the downloaded dependencies. +# restic-builder uses a different cache path and id to avoid sharing cache with velero-builder-helper and velero-builder. +RUN --mount=type=cache,target=/go/pkg/mod,id=vbb go mod download COPY . /go/src/github.com/vmware-tanzu/velero -RUN mkdir -p /output/usr/bin && \ - export GOARM=$( echo "${GOARM}" | cut -c2-) && \ - go build -o /output/${BIN} \ - -ldflags "${LDFLAGS}" ${PKG}/cmd/${BIN} && \ - go build -o /output/velero-helper \ - -ldflags "${LDFLAGS}" ${PKG}/cmd/velero-helper && \ - go clean -modcache -cache + +FROM velero-builder-base AS velero-builder-helper +RUN --mount=type=cache,target=/go/pkg/mod,id=vbb GOARM=$( echo "${GOARM}" | cut -c2-) go build -o /output/velero-helper \ +-ldflags "${LDFLAGS}" ${PKG}/cmd/velero-helper + +FROM velero-builder-base AS velero-builder +RUN --mount=type=cache,target=/go/pkg/mod,id=vbb GOARM=$( echo "${GOARM}" | cut -c2-) go build -o /output/${BIN} \ + -ldflags "${LDFLAGS}" ${PKG}/cmd/${BIN} # Restic binary build section FROM --platform=$BUILDPLATFORM golang:1.22-bookworm AS restic-builder @@ -63,12 +70,30 @@ ENV CGO_ENABLED=0 \ GOARCH=${TARGETARCH} \ GOARM=${TARGETVARIANT} -COPY . /go/src/github.com/vmware-tanzu/velero +# /output dir needed by last stage to copy even when BIN is not velero +RUN mkdir -p /output/usr/bin && mkdir -p /build/restic +WORKDIR /build/restic -RUN mkdir -p /output/usr/bin && \ - export GOARM=$(echo "${GOARM}" | cut -c2-) && \ - /go/src/github.com/vmware-tanzu/velero/hack/build-restic.sh && \ - go clean -modcache -cache +# cache go mod download before applying patches +RUN --mount=type=cache,target=/go/pkg/mod,id=restic if [ "${BIN}" = "velero" ]; then \ + git clone --single-branch -b v${RESTIC_VERSION} https://github.com/restic/restic.git . && \ + go mod download; \ + fi + +# invalidate cache if patch changes +COPY hack/fix_restic_cve.txt /go/src/github.com/vmware-tanzu/velero/hack/ + +# cache go mod download after applying patches +RUN --mount=type=cache,target=/go/pkg/mod,id=restic if [ "${BIN}" = "velero" ]; then \ + git apply /go/src/github.com/vmware-tanzu/velero/hack/fix_restic_cve.txt && \ + go mod download; \ + fi + +# arch specific build layer +RUN --mount=type=cache,target=/go/pkg/mod,id=restic if [ "${BIN}" = "velero" ]; then \ + GOARM=$(echo "${GOARM}" | cut -c2-) go run build.go --goos "${GOOS}" --goarch "${GOARCH}" --goarm "${GOARM}" -o /output/usr/bin/restic && \ + chmod +x /output/usr/bin/restic; \ + fi # Velero image packing section FROM paketobuildpacks/run-jammy-tiny:latest @@ -77,6 +102,8 @@ LABEL maintainer="Xun Jiang " COPY --from=velero-builder /output / +COPY --from=velero-builder-helper /output / + COPY --from=restic-builder /output / USER cnb:cnb