Рекомендации по работе с Docker для Golang-разработчиков (Multistage Building)

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

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

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", HelloServer)
	fmt.Printf("Starting server at port 8080\n")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}

func HelloServer(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello world")
}

Сначала, соберем Docker образ в один этап:

FROM golang:1.16-alpine
RUN mkdir /build
WORKDIR /build
COPY go.mod .
#COPY go.sum .
RUN go mod download
COPY . .
RUN go build -o /main main.go
ENTRYPOINT ["/main"]

На выходе мы получили Docker образ, размер которого 308 MB. Давайте, теперь мы пересоберем тоже самое приложение, но с использованием многоэтапной сборки:

# Этап, на котором выполняется сборка приложения
FROM golang:1.16-alpine as builder
RUN mkdir /build
WORKDIR /build
COPY go.mod .
#COPY go.sum .
RUN go mod download
COPY . .
RUN go build -o /main main.go
# Финальный этап, копируем собранное приложение
FROM alpine:3
COPY --from=builder main /bin/main
ENTRYPOINT ["/bin/main"]

Мы получили Docker образ, размер которого всего 11.8 MB. Неплохо, мы уменьшили образ в более, чем 25 раз. Но, за счет чего нам удалось добиться такого результата?

В первом случае, мы используем сборку в один этап, а следовательно размер финального Docker образа состоит из размера golang:1.16-alpine (302 MB) + размер исходников (0.5 MB) + размер скомпилированного приложения (6.2 MB).

Во, втором случае, мы выполнили компиляцию и сборку приложения, а затем в финальный этап, перенесли уже скомпилированный результат. Таким образом, для создания Docker образа используется лишь один, финальный этап, который состоит из размера alpine:3 (5.59 MB) + размер скомпилированного приложения (6.2 MB).

А можно ли еще уменьшить размер Docker образа?

Можно, но для этого в качестве финального образа, мы должны использовать docker scratch - это пустой образ в докере, размер которого 0 MB.

FROM golang:1.16-alpine as builder
RUN mkdir /build
WORKDIR /build
COPY go.mod .
#COPY go.sum .
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /main main.go
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder main /bin/main
ENTRYPOINT ["/bin/main"]

В итоге наш контейнер занимает всего лишь 6.34 MB (размер скомпилированного приложения). На что стоит обратить внимание?

Первое, нам пришлось изменить команду сборки, а именно добавить дополнительные флаги:

CGO_ENABLED - мы отключаем CGO, таким образом мы получаем скомпилированное Go-приложение вместе с статически связанными C-библиотеками, поэтому наш бинарник будет работать без каких-либо внешних зависимостей. Более подробно, можно почитать тут.

GOOS - мы указываем Linux в качестве ОС.

Второе, на что стоит обратить внимание - это SSL. Т.к. scratch пуст, то там просто нету рутовых SSL сертификатов, а значит их нужно добавить вручную.

Источник: https://habr.com/ru/post/647255/


Интересные статьи

Интересные статьи

Выгрузка пользователей из 1C ЗУП в Битрикс24 или правдивая история о том как настроить интеграцию 1С-Битрикс24 с ЗУП без 1С-ника.В жизни так бывает, причём бывает чаще чем хотелось бы, хоть в целом и ...
Пришел ко мне коллега и спросил: "Как проигнорировать .dockerignore при сборке docker-образа?" После совместных поисков и проверок, было найдено простое решение, состоящее в сл...
Что нас побудило создать курс по Docker — хотя на рынке десятки предложений по этой теме, и практически каждая IT-школа отметилась в этом направлении? Побудили нас студенты «Вечерней...
В 1С Битрикс есть специальные сущности под названием “Информационные блоки, сокращенно (инфоблоки)“, я думаю каждый с ними знаком, но не каждый понимает, что это такое и для чего они нужны
Фираза недавно назначили директором компании стоимостью в миллиард долларов, где он работал на различных должностях в течение девяти лет. Два года он добивался этой позиции, но, получив её, Ф...