как ускорить запуск Go приложения в Docker уменьшить размер образа
Рейтинг: 62.7% · 30 голосов
Войдите, чтобы голосовать
Голосовать «За» и «Против» могут только авторизованные пользователи. Войдите в свой аккаунт — или зарегистрируйтесь, это займёт минуту.
Нет аккаунта? Зарегистрироваться
как ускорить запуск Go приложения в Docker уменьшить размер образа
Собираю Go-сервис в Docker, итоговый образ выходит 800MB+, и каждый раз при деплое приходится ждать пока скачается. Коллеги говорят что Go-образы должны быть маленькими, но у меня почему-то нет. Использую FROM golang:1.22 как базовый образ. Как правильно уменьшить размер и ускорить сборку?
✔ Лучший ответ выбран автором темы — tsav
Классическое решение — multi-stage build. В первом стейдже собираешь бинарь, во втором копируешь только его в минимальный базовый образ. Вот рабочий шаблон: FROM golang:1.22-alpine AS builder / WORKDIR /app / COPY go.mod go.sum ./ / RUN go mod download / COPY . . / RUN CGO_ENABLED=0 GOOS=linux go build -ldflags='-w -s' -o server . / FROM scratch / COPY --from=builder /app/server / ENTRYPOINT…
✔ Лучший ответ сформирован автоматически — rbacker
Никто не упомянул кеш-маунты BuildKit, а на повторных сборках они дают больше всего: RUN --mount=type=cache,target=/go/pkg/mod и второй такой же на /root/.cache/go-build. В отличие от слоёного кеша они переживают даже изменение go.mod — перекачиваются только новые модули, а инкрементальный кеш компилятора сохраняется между сборками. У нас CI-сборка с четырёх минут упала до сорока секунд…
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
✔ Лучший ответ — выбран автором
Классическое решение — multi-stage build. В первом стейдже собираешь бинарь, во втором копируешь только его в минимальный базовый образ. Вот рабочий шаблон: FROM golang:1.22-alpine AS builder / WORKDIR /app / COPY go.mod go.sum ./ / RUN go mod download / COPY . . / RUN CGO_ENABLED=0 GOOS=linux go build -ldflags='-w -s' -o server . / FROM scratch / COPY --from=builder /app/server / ENTRYPOINT ["/server"]. Образ FROM scratch — буквально пустой, итог будет 10-20MB вместо 800.
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
Флаги -ldflags='-w -s' важны: -w убирает DWARF debug info, -s убирает symbol table. Вместе дают 30-40% уменьшение размера бинаря. CGO_ENABLED=0 критично для FROM scratch — иначе бинарь динамически слинкован с libc и не запустится в пустом образе.
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
FROM scratch круто, но неудобно если нужны SSL-сертификаты или timezone data. Тогда лучше FROM alpine:3.19 — образ 5MB, есть /etc/ssl/certs и musl libc. Либо используй gcr.io/distroless/static-debian12 от Google — тоже минимальный, но с сертификатами и без shell (что плюс для безопасности).
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
Для ускорения самой сборки в CI — кешируй слои правильно. Копируй go.mod и go.sum отдельно до COPY . . и запускай go mod download до копирования исходников. Тогда зависимости кешируются в отдельном слое и не перекачиваются при изменении кода. Это самое частое упущение — люди делают COPY . . / RUN go mod download и теряют весь кеш при любом изменении файла.
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
Ещё совет: используй .dockerignore. Без него COPY . . затягивает .git, vendor если есть, тесты, документацию — всё это идёт в build context и раздувает время отправки в демон. Минимальный .dockerignore: .git, .gitignore, *.md, *_test.go, Dockerfile.
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
Проверить итоговый размер слоёв удобно через docker image inspect или docker history --no-trunc image:tag. Ещё есть утилита dive — визуально показывает что в каждом слое занимает место. Очень помогает найти случайно затянутые тестовые данные или логи сборки.
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
✔ Лучший ответ — сформирован автоматически
Никто не упомянул кеш-маунты BuildKit, а на повторных сборках они дают больше всего: RUN --mount=type=cache,target=/go/pkg/mod и второй такой же на /root/.cache/go-build. В отличие от слоёного кеша они переживают даже изменение go.mod — перекачиваются только новые модули, а инкрементальный кеш компилятора сохраняется между сборками. У нас CI-сборка с четырёх минут упала до сорока секунд. Multi-stage из ответов выше обязателен в любом случае, кеш-маунты его дополняют, а не заменяют.
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
@tsav, про scratch и сертификаты есть трюк проще, чем переезжать на alpine: COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ — и TLS работает. А таймзоны с Go 1.15+ вшиваются в бинарь тегом сборки timetzdata: плюс ~450 КБ к бинарю, зато образ остаётся пустым. Distroless беру только когда нужен nonroot-юзер из коробки, в остальном scratch с этими двумя добавками закрывает всё.
Re: как ускорить запуск Go приложения в Docker уменьшить размер образа
@archlord, dive хорош не только руками — у него есть режим CI=true с порогом efficiency, который фейлит сборку, если кто-то опять затащил мусор в слой. Мы так однажды поймали 200 МБ тестовых фикстур, которые забыли добавить в .dockerignore: глазами в docker history никто бы не полез, а пайплайн упал сразу.
Поделиться темой:
✈ Telegram
VK
- Похожие темы
-
- Поставил все сиды, а loss всё равно гуляет между запусками — кто победил недетерминизм в PyTorch?
17 ответов · 821 просмотров
-
-
-
-
-
- Dockerfile глубже: ENTRYPOINT и CMD, HEALTHCHECK, .dockerignore, запуск не от root
4 ответов · 95 просмотров
Похожие запросы:
docker compose как пользоватьсякак написать dockerfileкак уменьшить размер docker образачто такое docker hub и как им пользоватьсякак собрать docker образ из dockerfileлучшие практики написания dockerfile
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость