29.06.2020 docker компиляция upx ldflags
Docker поддерживает все семейства ОС — Linux, Unix, Windows, MacOS. Также он реализует контейнеризацию на уровне ОС, что означает незначительные накладные расходы на запуск контейнера.
Docker — один из самых популярных систем контейнеров. Поддерживается многими популярными хостингами, такими как Microsoft Azure, Amazon, Digital Ocean.
Создание docker-образа выполняется с помощью команды docker build
при наличии файла Dockerfile
.
FROM rhaps1071/golang-1.14-alpine-git AS build WORKDIR /build COPY . . RUN CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -ldflags "-s -w -extldflags '-static'" -o ./app RUN apk add upx RUN upx ./app FROM scratch COPY --from=build /build/app /app ENTRYPOINT ["/app"]
Благодаря использованию модулей GO, при компиляции проекта нам нет необходимости
перемещать исходники в какую-либо специфическую папку, а также нет необходимости
скачивать зависимости — GO делает это сам при выполнении go build
.
Образ будет передаваться по сети, его размер должен быть как можно меньше, иначе сборка и деплой будут занимать больше времени.
Поэтому, в данном Dockerfile
мы проводим сборку бинарного файла в одном окружении —
rhaps1071/golang-1.14-alpine-git
,
а итоговый образ выдаем в виде scratch
с добавлением нашего файла.
Для сборки GO программы нам необходим достаточно весомый образ (c исходными кодами самого GO,
множеством утилит). Однако все это не нужно нам в продакшне. Для продакшна нам необходим только
бинарный файл программы.
scratch
— встроенный docker-образ нулевого размера.
Таким образом размер итогового образа будет равен размеру бинарного файла, что составляет несколько мегабайт.
Мы можем влиять на размер двумя путями:
Флаги -s -w
убирают отладочную информацию. В моем случае с ними файл уменьшился с 15MB до 11MB.
Использование upx
уменьшило файл с 11MB до 4.1MB.
Флаги -extldflags '-static'
использованы для статической линковки бинарного файла.
Результатом стандартной динамической линковки является бинарный файл, требующий наличия в системе
внешних библиотек (файлы .so в Linux).
Зависимость бинарного файла в Linux от внешних библиотек можно посмотреть командой ldd
.
В scratch
, alpine
у нас не будут установлены внешние библиотеки,
так как это очень минималистичные образы.
В этом случае мы пользуемся статической линковкой — все внешние библиотеки будут скомпилированы
внутрь нашего бинарного файла.
Исходные файлы доступны в репозитории Github.