В предыдущей заметке я обозначил проблему с размером docker-образа. Для моего простенького приложения он получался более 800 мегабайт.

Дело в том, что сборка приложения происходила внутри контейнера с практически полноценной debian (или какой хотите) системой. Но у нас же Go! Мы же можем собрать бинарный файл заранее под любую архитектуру.

Делается это, как оказалось, довольно просто.

Первым этапом компилируем наше приложение, вторым - собираем докер-контейнер на основе образа scratch. Образ scratch - это такой образ докера, который не содержит вообще ничего. Правда он не содержит и необходимых Go C-библиотек. Но эту проблему решит компилятор golang, который можно заставить собрать приложения статически, с включением всего необходимого.

Итак, говорим компилятору CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .. В нашем рабочем каталоге появится бинарный файл main под linux-архитектуру.

Делаем Dockerfile примерно следующего содержания:

# Сборка на основе пустого образа
FROM scratch

# Добавляем бинарный файл main в корень образа
ADD main /

# Здесь важно! Шаблоны и прочие внешние файлы в наш бинарник не включены
# Поэтому их следует скопировать в соответствующую папку контейнера
# Обратите внимание - при копировании пачки файлов по маске *.msg, каталог в контейнере должен заканчиваться закрывающим слэшем ...mail/
ADD ./templates/mail/*.msg /templates/mail/

ENV API_BOLTDB_PATH='bolt.db'
ENV API_HOSTNAME=':8080'

CMD ["/main"]

EXPOSE 8080

Отдельный момент. При сборке образа from scratch не будет работать команда RUN - помним, что системы внутри контейнера нет.

Дальше говорим docker build -t imagename . Всё, приложение собрано и будет работать после запуска командой docker run ...

Образ получается размером в десяток мегабайт. Вундебар!) Docker сборка Golang контейнера