Ускоряем сборку Go приложения в Docker

Перед тем как просто копировать код приложения в контейнер для дальнейшей компиляции (то есть писать что-то такое)

COPY . .

Сначала скопируйте файлы go modules и загрузите зависимости. Это позволит избежать повторных загрузок пакетов разместив их в module cache

COPY go.mod go.sum .
RUN go mod download
COPY . .

Вторым этапом подключаем переиспользование build кэша. Заменяем выражение вида

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .

На выражение вида

ENV GOCACHE=/root/.cache/go-build
RUN --mount=type=cache,target="/root/.cache/go-build" CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .

Время пересборки приложения при внесении изменений в код:

Итоговые файлы и время пересборки после изменения кода

ДО (22,807s):

FROM golang:1.22-alpine3.19 as builder

WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
FROM alpine:3.19

WORKDIR /root/
COPY --from=builder /src/app .
CMD ["./app"]

ПОСЛЕ (3,127s):

FROM golang:1.22-alpine3.19 as builder

WORKDIR /src
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
ENV GOCACHE=/root/.cache/go-build
RUN --mount=type=cache,target="/root/.cache/go-build" CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
FROM alpine:3.19

WORKDIR /root/
COPY --from=builder /src/app .
CMD ["./app"]