Docker — это мощный инструмент для создания легковесных, переносимых и согласованных сред для запуска приложений. Одной из проблем, с которыми сталкиваются разработчики, является минимизация размера образов Docker, что может существенно повлиять на производительность и использование ресурсов приложениями. В этой статье мы рассмотрим, как создать небольшой образ Docker для приложения Golang, используя многоэтапные сборки.

Многоэтапные сборки позволяют создавать несколько промежуточных образов в процессе сборки, каждый из которых оптимизирован для конкретной задачи. Таким образом, вы можете минимизировать окончательный размер образа, поскольку включаете только необходимые файлы и зависимости.

Начнем с простого «Hello, World!» Приложение Голанг:

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

Теперь давайте создадим многоэтапный Dockerfile для создания и минимизации размера приложения Golang:

# Stage 1: Build the application
FROM golang:1.17 AS build

WORKDIR /app
  
  # Copy the source code
COPY . .
  
  # Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -o main
  
  # Stage 2: Create a minimal image only with the binary
FROM scratch

COPY --from=build /app/main /main
  
  # Set the entrypoint
ENTRYPOINT ["/main"]

В этом Dockerfile мы используем два этапа:

  1. Этап сборки. Мы начинаем с базового образа golang:1.17 и настраиваем рабочий каталог. Затем мы копируем исходный код в образ и собираем двоичный файл с помощью команды go build. Установив CGO_ENABLED=0 и GOOS=linux, мы гарантируем, что наш бинарный файл статически связан и совместим с операционной системой Linux.
  2. Заключительный этап: мы используем минимальный базовый образ scratch, который представляет собой пустой образ, содержащий только необходимые компоненты для запуска статически связанного двоичного файла. Мы копируем двоичный файл со стадии сборки в окончательный образ и устанавливаем его в качестве точки входа.

И окончательный размер на моей машине составляет 1,84 мб по сравнению с 808 мб, когда мы не используем многоэтапную сборку.

Используя многоэтапные сборки, мы можем сохранить наш окончательный образ небольшим и включать только необходимые файлы, что приводит к минимальному образу Docker для нашего приложения Golang. Такой подход может значительно улучшить производительность, использование ресурсов и время запуска контейнерных приложений.

Заключение

Многоэтапные сборки — это мощный метод оптимизации образов Docker, особенно для приложений Golang. Используя эту функцию, вы можете создавать легкие и эффективные образы, которые идеально подходят для развертывания ваших приложений в производственных средах.

Если вам нравится читать статьи на Medium и вы заинтересованы в том, чтобы стать участником, я буду рад поделиться с вами своей реферальной ссылкой!

https://medium.com/@adamszpilewicz/membership