Comments 13
Можно ещё убрать отладочные символы (стектрейсы правда испортятся), да и сертификаты можно монтировать с хост-системы, но это уже мелочи конечно.
У подобного способа есть один минус: отсутствует кеширование при построении контейнера. Это довольно критично, если у вас много зависимостей, которые долго скачиваются либо собираются.
Как вариант, на одном из шагов можно удалять лишние данные из контейнера, чтобы уменьшить его размер.
Насколько я помню это зависит от сборщика. Например kaniko точно умеет в кеширование слоев в multi-stage
Докер не будет пересобирать слой если в нем не увидел изменений.
В Docker кешируются слои только для последнего stage. По крайней мере так было до 2021, далее с multistage building не работал.
Как справедливо отметил @sergeykons, у других сборщиков поведение может отличаться.
В Docker кешируются слои только для последнего stage. По крайней мере так было до 2021, далее с multistage building не работал.
не буду спорить, может так и было. Сейчат @Deissh прав. Но важно сначала копировать и скачивать файлы зависимостей а только потом сам проект. Зависимости не так часто меняются и этот слой не будет пересобираться.
COPY go.mod go.sum ./
RUN go mod download
# copy all sources
COPY . .
Можно накинуть несколько уточнений
1 go.mod и go.sum нужно все таки копировать в одной инструкции COPY чтобы не создавать лишний слой
2 Если использовать scratch то очень легко поймать проблемы с сертификатами (Которые нужно копировать из alpine) или таймзонами или любыми другими зависимостями. Можно использовать distroless
3 RUN mkdir вначале не нужен. WORKDIR сам создает директорию
Зачем вам компилировать внутри докера go build... ? Если можно компилировать на своём компьютере без докера :-)
Такой подход не всегда удобен, например если сборка происходит в пайплайне CI/CD, тогда придется устанавливать зависимости и golang.
Еще есть проблема с тайм-зонами. Не уточнял не добавили ли в последнюю версию, но в каком то 1.15-1.16 нужно было еще пробрасывать бд с таймзонами к бинарю (если вам будут прилетать данные не в UTC и надо будет конвертить в UTC). Плюс, если у вас используются C программы, то может использоваться C dns resolver и могут быть проблемы с резолвингом хостов в docker-compose окружениях по имени сервисов. И решается использованием -tags netgo
или GODEBUG=netdns=go
Рекомендации по работе с Docker для Golang-разработчиков (Multistage Building)