Docker для Go (multi-stage)
Тема дорожной карты · Golang
Контейнеризация Go-приложений с помощью Docker — естественное сочетание, поскольку Go создаёт статически скомпонованные бинарники, способные работать в самых небольших базовых образах, минимизируя площадь атаки и размер образа. Стандартный подход — многоэтапный Dockerfile: первый этап использует официальный образ golang:1.22 для выполнения go mod download и CGO_ENABLED=0 go build, а второй этап копирует только скомпилированный бинарник в образ scratch или gcr.io/distroless/static-debian12. Целевая архитектура задаётся через GOOS=linux и GOARCH=amd64 (или arm64 для Raspberry Pi / ARM-узлов) на этапе сборки, что делает кросс-компиляцию частью процесса сборки контейнера. Docker Compose (docker-compose up) широко используется для запуска Go-сервиса вместе с зависимостями — PostgreSQL, Redis или mock gRPC-сервером — для локальной разработки и интеграционного тестирования. При развёртывании в Kubernetes контейнеризованный Go-бинарник оборачивается в манифест Deployment с liveness и readiness-пробами на облегчённый эндпоинт /healthz, graceful shutdown управляется через terminationGracePeriodSeconds, а метрики собираются Prometheus.
Как это работает
Docker для Go (multi-stage) знаменито прост: go build создаёт один статический бинарь, запускаемый на любом хосте с тем же OS+arch. Кросс-компиляция через GOOS=linux GOARCH=amd64 go build. Контейнеризуйте бинарь через FROM scratch или FROM gcr.io/distroless/static (несколько МБ total). go build -ldflags="-s -w" — для удаления debug-символов (меньше бинарь). Health-эндпойнты: /healthz, /readyz. Graceful shutdown через http.Server.Shutdown(ctx).
Когда применять
Multi-stage Dockerfile: builder-образ гонит go build; runner — scratch или distroless с одним бинарём + CA-сертификатами. Всегда graceful SIGTERM — drain in-flight запросы до выхода. Версию встраивайте через -ldflags "-X main.Version=$(git describe)" для вывода myapp version. Запуск под non-root, read-only ФС, минимальные capabilities.
Типичные ошибки
Ловушки Docker для Go (multi-stage): FROM alpine, но компиляция против glibc (CGO_ENABLED=1 + alpine = мистические крэши — используйте CGO_ENABLED=0); нет CA-сертификатов в scratch-образах (TLS валится x509-ошибками — добавьте ca-certificates); нет graceful shutdown (k8s rolling-деплои дропают in-flight запросы); огромные бинари из-за забытых -w -s-флагов.