MXStat
MXStat
Введите текст для поиска
Расширенный поиск каналов
  • Вход на сайт
  • Каталог
    Каталог каналов Региональные подборки Поиск каналов
    Добавить канал
  • Рейтинги
    Рейтинг каналов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Max
Библиотека Go (Golang) разработчика

6 Oct, 08:30

Открыть в Max Поделиться

🐳 Идеальный Dockerfile для Go. Худеем с 800 МБ до 10 МБ

Знакомая картина: джун приносит микросервис, который делает пару запросов к БД, а Docker-образ весит под гигабайт. Почему? Потому что в FROM гордо красуется golang:latest.

Вместе с вашим кодом в продакшен уезжает весь тулчейн компилятора, операционная система, куча утилит (шелл, curl) и, как бонус, пачка потенциальных уязвимостей.

Прелесть Go в том, что он компилирует всё в один независимый бинарный файл. Нам не нужен Go в рантайме! Наш путь - Multi-stage builds (Многоэтапная сборка).

Вот "золотой стандарт" Dockerfile, который работает в 99% случаев:

# === Этап 1: Сборка (Builder) ===
FROM golang:1.22-alpine AS builder

WORKDIR /app

# Шаг 1: Кэшируем зависимости
# Этот слой пересоберется ТОЛЬКО если изменились go.mod или go.sum
COPY go.mod go.sum ./
RUN go mod download

# Шаг 2: Копируем код
COPY . .

# Шаг 3: Собираем бинарник
# CGO_ENABLED=0 - критически важно для статической линковки
# -ldflags="-w -s" - вырезаем отладочную информацию
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /app/bin/service ./cmd/server/main.go

# === Этап 2: Финальный образ (Runner) ===
# Используем distroless вместо alpine или scratch
FROM gcr.io/distroless/static-debian12:nonroot

WORKDIR /app

# Забираем только готовый бинарник из первого этапа
COPY --from=builder /app/bin/service .

# Контейнер будет работать от непривилегированного пользователя
USER nonroot:nonroot

EXPOSE 8080
ENTRYPOINT ["/app/service"]

Разбираем нюансы под капотом (Senior Edition):

• Зачем нужен CGO_ENABLED=0? По умолчанию Go может динамически линковаться с системными C-библиотеками (например, libc). Если вы соберете такой бинарник и положите в пустой образ, он упадет при старте. Отключая CGO, мы принудительно делаем статическую линковку - всё необходимое запекается прямо внутрь файла.

• Флаги -ldflags="-w -s": Они вырезают DWARF-таблицы и символы отладки. Это бесплатно срезает ~20-30% веса бинарника. Не переживайте, трейсы паник (stack traces) всё ещё будут показывать номера строк, так что для прода это безопасно.

• Почему distroless/static, а не scratch или alpine? * В scratch (абсолютно пустом образе) нет корневых сертификатов (ca-certificates). Как только ваш сервис попытается сделать внешний HTTPS-запрос, он упадет. Там также нет таймзон (tzdata).
- В alpine есть sh (шелл) и пакетный менеджер apk - это векторы атаки для хакеров, если они найдут RCE в вашем коде.
- Google Distroless содержит только сертификаты, таймзоны и юзера nonroot. Идеальный баланс микроскопического размера (~2 МБ) и безопасности.

У кого образы до сих пор весят больше 50 МБ - срочно переписывать!

#golang #docker #devops #architecture #security

👉 @golang_lib

156 4
Каталог
Каталог каналов Подборки каналов Поиск каналов Добавить канал
Рейтинги
Рейтинг каналов Max
Контакты
Написать в Max Написать в Telegram Написать на почту
Всякая всячина
Пользовательское соглашение Политика конфиденциальности
Наши каналы
MXStat в Telegram MXStat в Max
Наши боты
MXAuthBot MXAnalyticsBot
Made by TGStat