Comments 12
Jenkins ещё сюда добавить надо, чтоб сборки и тесты автоматом делались при коммите в гит и т.д.
Или Gitlab. Он и проект хранит, и реестр докер образов и пайплайны в нём.
Отличная статья для тех, кто вообще ничего про Докер не слышал. Все на пальцах объяснено, понятно, что происходит. Я помню себя несколько лет назад, когда пытался понять, что это и зачем — ни в одной статье человеческим языком не было объяснено.
Тех, кто вообще ничего про Докер не слышал, подобные несогласованные определения только запутают:
Docker image это шаблон только для чтения с инструкциями по созданию контейнера.

Docker контейнер — это запускаемый экземпляр image.

Возможно кого-то это может запутать, именно на такой случай статья содержит большое количество ссылок на документацию к docker. Эти определения взяты оттуда же.

Если проект большой, то можно в докере подмонтировать глобальный volume для промежуточных файлов сборки. Чтобы не пересобирать каждый раз с нуля.

При старте контейнер запускает только команду, которая указана в ENTRYPOINT или CMD, и останавливается при ее завершении.

Это неверно. Команда, которая выполняется при запуске контейнера получается, условно, путем склеивания ENTRYPOINT и CMD. Причем оба параметры могут переопределены при docker run


Чтобы этого избежать, можно при каждой сборке клонировать git-репозиторий внутрь контейнера, как, например, в файле:

Это худшая из идей. Нужно для начала определиться — для чего мы используем образ. Если для дистрибуции нашего софта, то git clone в докерфайле быть не должно. Как минимум из соображений того, что нам на приватные гит репозитории придется в докерфайле ещё как-то прописать ключи доступа. Ну, и, очевидно, что в образе хранить их не очень.
Второй момент, что если мы образ докера используем для фиксации версии сборочного тулинга, то это другая ситуация и исходники можно передавать как volume (опять же нет необходимости делать git clone внутри докерфайла)
Третий момент, который хочется подсветить — касается кэширования. Действительно, что докер пытается все кэшировать. И, соответственно, если в докерфайле написан "git clone", то докер может подумать, что изменений нет. Именно поэтому рекомендуется исходники инжектировать в образ через команду COPY, которая, как следует из названия, копирует файлы с машины разработчика внутрь образа. И в случае изменения любого файла в каталоге, передаваемом внутрь, докер увидит изменения. Либо есть ещё интересный воркераунд с передачей build-args и директивой ARG. Если внутрь образа подкидывать, например, текущую дату, то все после соответстввющей инструкции ARG будет инвалидировано и, как следствие, пересобрано. В принципе, это нормальная, описанная практика, хотя и выглядит как небольшой костыль


Ещё можно использовать docker multistage.

Команда, которая выполняется при запуске контейнера получается, условно, путем склеивания ENTRYPOINT и CMD.

Не совсем так, в документации написано, что, кроме склеивания, ENTRYPOINT может полностью затирать CMDhttps://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact.


Это важное замечание, и в статью добавлена информация о том, что ENTRYPOINT и CMD могут быть указаны вместе.


По поводу клонирования git-репозитория внутрь контейнера.


Такое поведение полезно, когда комиты попадают в мастер только через pull request (это позволяет выполнить, как минимум, сode review ). При таком подходе происходит разделение ролей — одни пишут код, другие выполняют сode review, а третьи выпускают версии (создают тег с новой версией в репозитрии и выполняют сборку релиза из добавленного тега). Клонирование репозитория с нужным тэгом внутрь контейнера, как минимум, упрощает сборку новой версии (не придется руками выполнять команду git checkout ...). Так же, такое поведение исключает вероятность того, что папка с исходниками может содержать незакомиченный код, ветку разработки и пр.


Использование сборки с volume так же описана в статье.


Нужно для начала определиться — для чего мы используем образ.

В данной статье образ используется только для сборки. Если есть приватный репозиторий, то данные для аутентификации могут быть проброшены в контейнер, например через параметры -e, --env, --env-file команды docker run.


Третий момент, который хочется подсветить — касается кэширования.

Это полезное добавление. Я упустил из виду возможность использовать COPY для копирования исходников внутрь контейнера.

Не совсем так, в документации написано, что, кроме склеивания, ENTRYPOINT может полностью затирать CMD —

Ну, там написано, что если меняете ENTRYPOINT, то CMD обнуляется.
Плюс есть немного магии с sh -c
А, в целом, это не противоречит написанному мной.


Так же, такое поведение исключает вероятность того, что папка с исходниками может содержать незакомиченный код, ветку разработки и пр.

Небольшая ремарка. У вас все равно должна быть система сборки и хранения кода. Например, гитлаб. И она гарантирует, что сборка не сможет быть произведена для кода, который не в репозитории. А разработчику МОЖЕТ быть нужно проверить код, который в его локальную копию репозитория ещё не попал. Это тонкости и, наверное, не предмет для спора. Но именно по совокупности — я за COPY исходников, а лучше — за подключение их в виде volume/bind-mount в сборочный контейнер (т.к. тот же гитлаб/jenkins etc. сами делают git clone в известное место известного коммита/ветки/тэга).


Если есть приватный репозиторий, то данные для аутентификации могут быть проброшены в контейнер, например через параметры -e, --env, --env-file команды docker run.

Принимается, но опять же — этой проблемы можно избежать, если исходники есть. Сюда же можно приплести гит-субмодули, если требуется сборка проекта из нескольких репозиториев (тогда создаётся убер-репозиторий, в который все остальные включены как субмодули с правильными версиями, и можно выкачать определенный срез-версию кодовой базы одним чохом, как говорится)

А знающие могут дать пример dockerfile для билдинга используя виндовый докер? Какой контейнер брать за основу, чтобы собирать проект на Windows (msbuild + cmake)?
Only those users with full accounts are able to leave comments. Log in, please.