Код-ревью Senior Dockerfile и multi-stage обновлено
Ревью: multi-stage для Go
Вопрос
Это multi-stage Dockerfile для Go-сервиса. Найди ошибки.
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN go mod download
RUN go build -o /out/api ./cmd/api
FROM alpine:3.20
COPY --from=build /src /src
COPY --from=build /out/api /api
ENTRYPOINT /api
Коротко
Исправленная версия: Статический бинарник без cgo запускается на любой минимальной базе, в финальном образе нет исходников, shell и root. Ошибка not found при существующем файле это классический признак несовпадения libc между стадиями.
Что должен найти ревьюер
- Производительностьстрока 3
COPY . .доgo mod download: кеш модулей сбрасывается при любой правке кода. СначалаCOPY go.mod go.sum ./иgo mod download. - Ошибкастрока 5Сборка без
CGO_ENABLED=0: бинарник может оказаться динамически слинкован с glibc и не запуститься на alpine (musl) с ошибкойnot found. - Безопасностьстрока 8В финальный образ копируются все исходники
/src: лишний размер и утечка кода и, возможно, конфигов. Нужен только бинарник. - Ошибкастрока 10Shell-форма ENTRYPOINT: запускается через
/bin/sh -c, сигналы не доходят до приложения. НужноENTRYPOINT ["/api"]. - БезопасностьНет
USER: процесс работает от root. Добавить непривилегированного пользователя или взять distroless сnonroot.
Разбор
Исправленная версия:
FROM golang:1.23 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/api ./cmd/api
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /out/api /api
USER nonroot
ENTRYPOINT ["/api"]
Статический бинарник без cgo запускается на любой минимальной базе, в финальном образе нет исходников, shell и root. Ошибка not found при существующем файле это классический признак несовпадения libc между стадиями.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.