29 июня 2020 г. Docker Compilation Upx Ldflags
Давайте обсудим, как создать минимальный Docker образ для Go программы.
Docker поддерживается многими операционными системами — Linux, Unix, Windows и macOS. Docker контейнеры также поддерживаются многими популярными хостинг-платформами — Microsoft Azure, Amazon Web Services, Digital Ocean и другими.
Сборка Docker образа выполняется с помощью команды docker build, а Dockerfile необходим для предоставления инструкций по сборке.
Давайте посмотрим на следующий 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 build.
Теперь давайте обсудим все особенности этого Dockerfile.
Размер Docker образа важен, потому что образ будет загружаться и скачиваться во время сборки и развертывания. Чем больше размер образа, тем больше времени вы потратите на передачу по сети.
На первом этапе (“build”) в Dockerfile я начинаю сборку с образа rhaps1071/golang-1.14-alpine-git, который представляет собой golang:1.14-alpine с установленным git.
Alpine — это самый маленький Linux образ, доступный в настоящее время. Размер его образа составляет около 3MB.
На втором этапе я использую scratch просто для размещения бинарного файла там.
scratch — это готовый Docker образ с нулевым размером. Это означает, что результирующий размер образа равен размеру бинарного файла.
Мы можем уменьшить размер бинарного файла, используя два подхода:
ldflags);Флаги -s -w удаляют отладочную информацию из бинарного файла. В моем случае размер был уменьшен с 15MB до 11MB благодаря этим флагам.
-extldflags '-static' используется для статической линковки бинарного файла даже при включенном CGO. Динамическая линковка делает наш бинарный файл зависимым от внешних библиотек (файлы .so в Linux).
Зависимости внешних библиотек можно проверить с помощью команды ldd для бинарного файла.
В scratch и Alpine у нас не установлены эти библиотеки. В этом случае нам приходится использовать статическую линковку — все библиотеки будут скомпилированы в наш бинарный файл программы.
Я также использовал инструмент upx для сжатия бинарного файла. Размер был уменьшен с 11MB до 4.1MB.
Исходный код этого примера можно найти в репозитории GitHub.
Ранее мы обсуждали локальную отладку с помощью IDE GoLand. Теперь мы обсудим, как удалённо отлаживать программу, работающую внутри Docker-контейнера, используя Visual Studio Code и GoLand IDE.
Read More → Docker Debugger Delve Vscode GolandРанее мы рассматривали деплой бинарного файла программы через SSH на сервер
Сейчас мы рассмотрим как реализовать деплой Docker контейнера из Gitlab CI.
Read More → Docker Deploy Gitlab Ci/CdУтилита и пакет Go для ожидания открытия портов (TCP, UDP).
Read More → Tcp Udp DockerДавайте рассмотрим, как работает компиляция Go и как использовать GitLab CI для этого.
Read More → Gitlab Compilation Deploy Ssh Modules Vendor Ci/Cd