Comments 34
Спасибо за пост.
Интересная фича. Сейчас как альтернативу образам сборки использую докеризированные команды, что в моём случае (интерпретируемые языки) вполне удобно.
использую докеризированные команды
Вы могли бы привести пример?
FROM golang:1.8.1-alpine
WORKDIR /go/src/github.com/username/project
ADD . ./
# Устанавливаем зависимости, необходимые для сборки
RUN apk add --no-cache --virtual .build-requirements \
git \
make \
# Запускаем сборку
&& make build \
# удаляем установленные выше пакеты
&& apk del .build-requirements
Если зависимостей сборки уйма, весь этот ком не забыть почистить… Не очень изящно, имхо.
т.е. помимо того, что, как написали выше, не получится сделать отладку, ещё и чистить сборочные образы придётся вручную? да ещё и промежуточных сборок не оставить.
В чём profit?
и да, отдельные докеры для сборки и запуска это возможность поддерживать их более централизованно. А так получается, на N-цать похожих сервисов придётся вместо одного докера-сборщика и одного докера-запускатора делать поддержку N-цати докеров
FROM ...
ARG APPLICATION=app=1.2.3
RUN apt-get install <dependencies> \
$APPLICATION
...
получается параметризованный образ, который по дефолту используется для запуска приложения, а когда нужно сделать сборку из командной строки в ARG передаю «devscripts debhelper ..» и все, что нужно для сборки.
Конечно во время сборки CMD тоже нужно оверрайднуть, docker run это позволяет.
Минус тот же, что уже обсуждали — нет кэширования, время сборки возрастает. После успешной сборки нужно еще раз запустить docker build
Плюс — собираю и запускаю юнит тесты фактически в той среде, в которой и запускаю готовое приложение
Best practice и при использовании новой фичи остаются актуальны: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/
Т.е. когда нужно собрать, забрать артефакты и уничтожить.
Опередили с постом :)
А с docker-compose уже пробовал кто проверять как дружит?
особенно для компилируемых языков.
Очень хороши когда нужно разложить артефакты сборки по разным контейнерам, например, для веб-приложения статику положить в контейнер nginx, а собственно приложение упаковать отдельно. До сих пор приходилось мудрить либо сборкой контейнеров отдельно с удалением ненужного на последней стадии (зачастую без уменьшения образа), либо использовать тома для доступа из nginx к контейнеру с артефактами.
Как в нём указать разные стейджи одного докерфвайла для разных сервисов? По идее должна быть поддержка --target, но ничего не нашёл по этому поводу, ни доках, ни в ишью/ПР.
Правда, есть практика использовать по одному Dockerfile на сервис. Поэтому, если есть общая часть какая-то, то может стоит вынести её в родительский image?
Некоторые фичи у них в параллели вводились, не чужие люди, как говорится.
Если создавать родительский образ, то возникает две проблемы:
- его избыточность (решается в принципе с помощью стейджинга, то есть делается родительский образ не для конечных образов, а для билдера, из которого нужный артефакт копируется в конечный)
- необходимость либо пересобирать вручную при изменении исходников/зависимостей, либо включать и его в список сервисов с фейковым запуском
Тогда уж проще иметь два почти одинаковых докерфайла, синкая их ручками.
Правда, есть практика использовать по одному Dockerfile на сервис.
Собственно раньше особо возможности не было использовать несколько сервисов на один докер-файл.
Чтобы не плодить сущности, например. Тем более, для некоторых технологий крайне желательно иметь одинаковые окружения сборки и выполнения, чтобы, например, ненужные полифилы в сборку не входили или, наоборот, чтобы нужные были.
Нововведение очень кстати и очень вовремя.
Как разделить окружение для сборки и запуска сервиса в Docker сегодня и как это cделать завтра